JS 代码片段

通常在開發要在網路上執行的 crate 時,您會希望在這裡和那裡包含一些 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 導入的,其中根目錄相對於 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_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 和預設的 bundler 輸出模式。若要支援 --target nodejs,我們需要將 ES 模組語法轉換為 CommonJS (計劃完成此操作,只是尚未完成)。此外,若要支援 --target no-modules,我們必須類似地將 ES 模組轉換為其他內容。

  • module = "..." 中的路徑目前必須以 / 開頭,或位於 crate 根目錄。它旨在最終支援類似 ./../ 的相對路徑,但目前認為這需要在 Rust proc_macro crate 中提供更多支援。

如上所述,有關注意事項的更多詳細資訊可在 RFC 6 中找到。