JS 代码片段

在开发要在 Web 上运行的板条箱时,您通常需要在其中包含一些 JS 代码。虽然 js-sysweb-sys 涵盖了许多需求,但它们并不涵盖所有内容,因此 wasm-bindgen 支持在 Rust 代码旁边编写 JS 代码,并将它们包含在最终的输出工件中。

要包含本地 JS 文件,您将使用 #[wasm_bindgen(module)]


# #![allow(unused_variables)]
#fn main() {
#[wasm_bindgen(module = "/js/foo.js")]
extern "C" {
    fn add(a: u32, b: u32) -> u32;
}
#}

此声明表明 extern 块中包含的所有函数都从文件 /js/foo.js 导入,其中根目录相对于板条箱根目录(Cargo.toml 所在的位置)。

wasm-bindgen 执行时,/js/foo.js 文件将进入最终的输出,因此您可以在库中使用 module 注释,而无需担心库的用户!

JS 文件本身必须使用 ES 模块语法编写

export function add(a, b) {
    return a + b;
}

如果您有兴趣,可以在 RFC 6 中找到此功能的完整设计。

使用 inline_js

除了 module = "..." 之外,如果您是宏作者,您还可以使用 inline_js 属性


# #![allow(unused_variables)]
#fn main() {
#[wasm_bindgen(inline_js = "export function add(a, b) { return a + b; }")]
extern "C" {
    fn add(a: u32, b: u32) -> u32;
}
#}

使用 inline_js 表示 JS 模块是在属性本身中内联指定的,并且没有从文件系统加载任何文件。它们与使用 module 时具有相同的限制和注意事项,但有时对于宏本身更容易生成。不建议手写代码使用 inline_js,而是尽可能利用 module

注意事项

虽然非常有用,但本地 JS 代码片段目前存在一些需要注意的注意事项。不过,其中许多是暂时的!

  • 目前,JS 文件中不支持 import 语句。这是一个我们将来可能会解除的限制,一旦我们确定了支持它的好方法。不过,现在,js 代码片段必须是独立的模块,不能从其他任何地方导入。

  • 目前仅支持 --target web 和默认的捆绑器输出模式。为了支持 --target nodejs,我们需要将 ES 模块语法转换为 CommonJS(这计划要完成,只是还没有完成)。此外,为了支持 --target no-modules,我们还需要类似地将 ES 模块转换为其他东西。

  • module = "..." 中的路径目前必须以 / 开头,或者以 crate 根目录为根目录。最终计划支持 ./../ 等相对路径,但目前认为这需要 Rust proc_macro crate 中提供更多支持。

如上所述,有关注意事项的更多详细信息可以在 RFC 6 中找到。