在 JavaScript 或 TypeScript 编写的 Worker 中,可以通过导入 Wasm 模块并使用 WebAssembly.instantiate() ↗ 实例化该模块来使用 Wasm。这可用于加速不涉及大量 I/O 的计算密集型操作。
本指南演示 Wasm 与 JavaScript 互操作的基础知识。
在本指南中,你将使用 WebAssembly 文本格式创建一个简单的 Wasm 模块,以了解导入和导出的工作原理。实际使用中,你不会以这种格式编写代码,而是使用你选择的编程语言直接编译为 WebAssembly 二进制格式(.wasm)。
查看以下示例模块(;; 表示注释):
;; src/simple.wat
(module
;; Import a function from JavaScript named `imported_func`
;; which takes a single i32 argument and assign to
;; variable $i
(func $i (import "imports" "imported_func") (param i32))
;; Export a function named `exported_func` which takes a
;; single i32 argument and returns an i32
(func (export "exported_func") (param $input i32) (result i32)
;; Invoke `imported_func` with $input as argument
local.get $input
call $i
;; Return $input
local.get $input
return
)
)使用 wat2wasm ↗ 将 WAT 格式转换为 WebAssembly 二进制格式:
wat2wasm src/simple.wat -o src/simple.wasmWrangler 会打包所有以 .wasm 或 .wasm?module 结尾的 Wasm 模块,使其在 Worker 运行时可用。这是通过默认打包规则完成的,可在 Wrangler 配置文件 中自定义。有关更多信息,请参阅 Wrangler 打包。
将 WAT 格式转换为 WebAssembly 二进制格式后,在现有的 JavaScript 或 TypeScript Worker 中导入并使用 Wasm 模块:
import mod from "./simple.wasm";
// Define imports available to Wasm instance.
const importObject = {
imports: {
imported_func: (arg: number) => {
console.log(`Hello from JavaScript: ${arg}`);
},
},
};
// Create instance of WebAssembly Module `mod`, supplying
// the expected imports in `importObject`. This should be
// done at the top level of the script to avoid instantiation on every request.
const instance = await WebAssembly.instantiate(mod, importObject);
export default {
async fetch() {
// Invoke the `exported_func` from our Wasm Instance with
// an argument.
const retval = instance.exports.exported_func(42);
// Return the return value!
return new Response(`Success: ${retval}`);
},
};调用时,此 Worker 应记录 Hello from JavaScript: 42 并返回 Success: 42,演示了从 JavaScript 调用带参数的 Wasm 方法以及反向调用的能力。
实际使用中,你可能会将所选语言(如 Rust)编译为 WebAssembly 二进制文件。许多语言提供 bindgen 来简化 JavaScript 与 Wasm 之间的交互。这些工具可能与 JavaScript 打包器集成,并提供 WebAssembly API 以外的 API 来初始化和调用 Wasm 模块。例如,请参阅 Rust wasm-bindgen 文档 ↗。
或者,要使用 Rust 编写完整的 Worker,Workers 在使用 workers-rs crate 时提供许多相同的 Runtime API 和绑定(binding)。有关更多信息,请参阅 Workers Rust 指南。