使用 WebAssembly 的 Node.js

WebAssembly 是一種高效能的組合語言,可從多種語言編譯,包括 C/C++、Rust 和 AssemblyScript。目前,它受到 Chrome、Firefox、Safari、Edge 和 Node.js 的支援!

WebAssembly 規範詳細說明了兩種檔案格式,一種是名為 WebAssembly 模組的二進制格式,具有 .wasm 擴展名,另一種是對應的文字表示形式,稱為 WebAssembly 文本格式,具有 .wat 擴展名。

關鍵概念

  • 模組 - 已編譯的 WebAssembly 二進位檔案,即 .wasm 檔案。
  • 記憶體 - 可調整大小的 ArrayBuffer。
  • 表格 - 一個可調整大小的引用型別陣列,不存儲於記憶體中。
  • 實例 - 將模組與其記憶體、表格和變數實例化。

要使用 WebAssembly,您需要一個 .wasm 二進位檔案和一組用於與 WebAssembly 通訊的 API。Node.js 通過全局的 WebAssembly 物件提供了必要的 API。

console.log(WebAssembly);
/*
Object [WebAssembly] {
  compile: [Function: compile],
  validate: [Function: validate],
  instantiate: [Function: instantiate]
}
*/

生成 WebAssembly 模組

有多種方法可用於生成 WebAssembly 二進位檔案,包括

  • 手動編寫 WebAssembly(.wat),然後使用工具(例如 wabt)將其轉換為二進位格式。
  • 使用 emscripten 與 C/C++ 應用程式。
  • 使用 wasm-pack 與 Rust 應用程式。
  • 如果您喜歡類似 TypeScript 的體驗,可以使用 AssemblyScript

其中一些工具不僅會生成二進位檔案,還會生成 JavaScript 的 "黏著" 代碼和相應的 HTML 檔案以在瀏覽器中運行。

如何使用它

一旦您擁有一個 WebAssembly 模組,您可以使用 Node.js 的 WebAssembly 物件來實例化它。

// Assume add.wasm file exists that contains a single function adding 2 provided arguments
const fs = require('node:fs');

const wasmBuffer = fs.readFileSync('/path/to/add.wasm');
WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
  // Exported function live under instance.exports
  const { add } = wasmModule.instance.exports;
  const sum = add(5, 6);
  console.log(sum); // Outputs: 11
});

與作業系統互動

WebAssembly 模組無法直接自行訪問作業系統功能。第三方工具 Wasmtime 可用於訪問此功能。 Wasmtime 利用 WASI API 來訪問作業系統功能。

資源