Node.js 与 WebAssembly
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 来访问操作系统功能。