JavaScript または TypeScript で書いた Worker から Wasm を使うには、Wasm モジュールをインポートし、WebAssembly.instantiate() ↗ でインスタンスを作成します。入出力が少なく、計算量の多い処理を高速化できます。
このガイドでは、Wasm と JavaScript の相互運用の基本を説明します。
このガイドでは、WebAssembly Text Format で簡単な Wasm モジュールを作り、インポートとエクスポートの動きを確認します。実務ではこの形式でコードを書くことはありません。好きなプログラミング言語で書き、WebAssembly Binary Format(.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 Binary Format に変換します。
wat2wasm src/simple.wat -o src/simple.wasmWrangler は、.wasm または .wasm?module で終わる Wasm モジュールをバンドルし、実行時に Worker 内で使えるようにします。これはデフォルトのバンドル規則で行い、Wrangler 設定ファイル でカスタマイズできます。詳細は Wrangler Bundling を参照してください。
WAT 形式を WebAssembly Binary Format に変換したら、既存の 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 バイナリにコンパイルすることが多いです。多くの言語には、JavaScript と Wasm のやり取りを簡単にする bindgen があります。これらのツールは JavaScript バンドラーと連携し、Wasm モジュールの初期化と呼び出しに WebAssembly API 以外の API を提供することがあります。例として、Rust の wasm-bindgen ドキュメント ↗ を参照してください。
あるいは Worker 全体を Rust で書く場合、workers-rs crate を使うと、多くの同じ Runtime APIs と バインディング が使えます。詳細は Workers の Rust ガイド を参照してください。