上一篇部落格文章闡述了 Rust 與 WebAssembly 領域工作小組對 Rust 與 WebAssembly 的整體願景。在本篇部落格文章中,我們將深入探討 wasm-bindgen 的細節、我們對它的願景,以及如何協助我們打造此願景

wasm-bindgen 促進 JavaScript 與編譯成 WebAssembly 的 Rust 之間的溝通。它讓您可以使用 Rust 結構、JavaScript 類別、字串等術語,而不是僅使用 WebAssembly 原始呼叫慣例支援的整數和浮動數值。您只需支付所使用的部分,因此使用 alert 函式並不會引入 requestAnimationFrame函式的未用繫結。此外,它設計為支援即將推出的“主機繫結”提案,而這將消除 WebAssembly 函式與原生 DOM 函式之間任何需要 JavaScript shim 函式的需求。由於 DOM API 呼叫可以在編譯 WebAssembly 時驗證,且無須在每次呼叫時動態檢查,因此此舉有望解鎖比 JavaScript 更快速的 DOM 存取。

wasm-bindgen 是共享基礎

我們正在為鎖定使用 wasm-bindgen 的 JavaScript 環境的 Rust 板條箱生態系統打造一個共享基礎。分享基礎表示分享原始 extern 匯入。每個使用網路 window.requestAnimationFrame 函式或 ECMAScript Object.freeze 函式的程式庫不應該需要自己撰寫 extern 匯入。

將所有這些 API 的繫結都放在一個地方應該可以讓大家輕鬆撰寫像建構在 postMessage API 上的 MPSC 頻道等非常精巧的函式庫以及其他網路使用的公用函式庫。

分享 ECMAScript 全域 API

依 ECMAScript 標準定義的每個 JavaScript 環境中可用的全域 API 都透過wasm_bindgen::js 模組提供。例如,Object.freeze 函式可以用 wasm_bindgen::js::Object::freeze 取得。

但我們尚未完成,且我們需要更多協助!新增更多這些全域 API 繫結是開始使用 wasm-bindgen 的絕佳方式,而且有許多工作可以在來自各種協力廠商的同時提取請求中完成!

查看 ECMAScript 全域 API 元議題 以提供協助!

分享網路 API

ECMAScript 的全域 API 並非故事的終點,我們也需要 Web 的 DOM API 的共享繫結,例如 window.requestAnimationFrameNode.prototype.appendChildWebSocket

所有 Web API 的類型、函數和方法均透過 WebIDL 指定,因此我們正在針對 wasm-bindgen 研究新的 WebIDL 前端。WebIDL 前端就緒時,我們計畫從所有標準取得所有 Web API 的介面定義並自動從中產生一個龐大的 -sys 式箱子。

我們所指的新「前端」是什麼?回想上篇部落格文章對 wasm-bindgen 架構的簡化說明。它是一個程序化巨集,會剖析描述 extern JavaScript 匯入和 Rust 中要匯出至 JavaScript 的元件至抽象語法樹 (AST) 的 #[wasm_bindgen] 註解。接著,它會循序經過 AST 並產生兩個結果:Rust 繫結程式碼,用於使用已匯入的 JavaScript 元件;JavaScript 繫結程式碼,用於使用已匯出的 Rust 元件。我們將負責將 #[wasm_bindgen] 宣告剖析至 AST 的程式碼稱為「程序化巨集前端」。

wasm-bindgen's current architecture

有了 WebIDL 前端,我們將引進一種建立 AST 的新方法:剖析 WebIDL 並將其定義轉為 wasm-bindgen 的 AST。使用 WebIDL 前端時,不再有 #[wasm_bindgen] 註解或程序化巨集,但在建構 AST 後的管線其餘部分仍然相同。

wasm-bindgen's new architecture with a WebIDL frontend

這聽起來很棒嗎?查看 wasm-bindgen 存放庫中標籤為「frontend:webidl」的問題,協助我們建置 WebIDL 前端!WebIDL 前端的程式碼存在於 wasm-bindgen/crates/webidl 中,如果您有任何問題,請隨時在 irc.mozilla.org 的 #rust-wasm 中 ping fitzgen 或在相關問題中留下意見。

特別感謝 @ohanar,他一直盡責地增加將各種 WebIDL 建構轉換為 wasm-bindgen 的 AST 的支援!我們需要更多像 @ohanar 一樣願意挺身而出的人。🙏