JS 代码片段
通常在开发要在 Web 上运行的 crate 时,您会希望在其中加入一些 JS 代码。 虽然 js-sys
和 web-sys
涵盖了许多需求,但它们并不能涵盖所有内容,因此 wasm-bindgen
支持在您的 Rust 代码旁边编写 JS 代码,并将其包含在最终的输出产物中。
要包含本地 JS 文件,您可以使用 #[wasm_bindgen(module)]
宏
#![allow(unused)] fn main() { #[wasm_bindgen(module = "/js/foo.js")] extern "C" { fn add(a: u32, b: u32) -> u32; } }
此声明表示 extern
区块中包含的所有函数都从文件 /js/foo.js
导入,其中根目录是相对于 crate 根目录(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)] 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 根目录为根目录。 最终打算支援./
和../
等相对路径,但目前认为这需要在 Rustproc_macro
crate 中提供更多支援。
如上所述,有关注意事项的更多详细信息,请参阅 RFC 6。