Node.js 與 WebAssembly

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

WebAssembly 規範詳細說明了兩種檔案格式:一種是副檔名為 .wasm 的二進位制格式,稱為 WebAssembly 模組;另一種是相應的文字表示形式,稱為 WebAssembly 文字格式,副檔名為 .wat

核心概念

  • 模組(Module)- 一個已編譯的 WebAssembly 二進位制檔案,即 .wasm 檔案。
  • 記憶體(Memory)- 一個可調整大小的 ArrayBuffer。
  • 表(Table)- 一個可調整大小的型別化陣列,其中包含未儲存在記憶體中的引用。
  • 例項(Instance)- 模組的例項化,包含其記憶體、表和變數。

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

.(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  = ('node:fs');

// Use the readFileSync function to read the contents of the "add.wasm" file
const  = .('/path/to/add.wasm');

// Use the WebAssembly.instantiate method to instantiate the WebAssembly module
WebAssembly.().( => {
  // Exported function lives under instance.exports object
  const {  } = ..;
  const  = (5, 6);
  .(); // Outputs: 11
});

與作業系統互動

WebAssembly 模組本身無法直接訪問作業系統的功能。可以使用第三方工具 Wasmtime 來訪問此功能。Wasmtime 利用 WASI API 來訪問作業系統功能。

資源