コンテンツにスキップ

JavaScriptにおけるWasm

Wasmは、JavaScriptまたはTypeScriptで書かれたWorker内から、Wasmモジュールをインポートし、WebAssembly.instantiate()を使用してこのモジュールのインスタンスを生成することで使用できます。これは、重要なI/Oを伴わない計算集約的な操作を加速するために使用できます。

このガイドでは、WasmとJavaScriptの相互運用性の基本を示します。

シンプルなWasmモジュール

このガイドでは、WebAssemblyテキスト形式を使用してシンプルなWasmモジュールを作成し、インポートとエクスポートの仕組みを理解します。実際には、この形式でコードを書くことはありません。代わりに、お好みのプログラミング言語を使用し、WebAssemblyバイナリ形式(.wasm)に直接コンパイルします。

以下の例のモジュールを確認してください(;;はコメントを示します):

;; src/simple.wat
(module
;; JavaScriptからの関数`imported_func`をインポート
;; これは単一のi32引数を取り、変数$iに割り当てます
(func $i (import "imports" "imported_func") (param i32))
;; 単一のi32引数を取り、i32を返す
;; `exported_func`という名前の関数をエクスポート
(func (export "exported_func") (param $input i32) (result i32)
;; 引数として$inputを使って`imported_func`を呼び出す
local.get $input
call $i
;; $inputを返す
local.get $input
return
)
)

wat2wasmを使用して、WAT形式をWebAssemblyバイナリ形式に変換します:

Terminal window
wat2wasm src/simple.wat -o src/simple.wasm

バンドル

Wranglerは、.wasmまたは.wasm?moduleで終わる任意のWasmモジュールをバンドルし、Worker内でランタイムに利用できるようにします。これは、wrangler.tomlでカスタマイズ可能なデフォルトのバンドルルールを使用して行われます。詳細については、Wranglerバンドリングを参照してください。

JavaScriptからの使用

WAT形式をWebAssemblyバイナリ形式に変換した後、既存のJavaScriptまたはTypeScript WorkerでWasmモジュールをインポートして使用します:

import mod from "./simple.wasm";
// Wasmインスタンスで利用可能なインポートを定義します。
const importObject = {
imports: {
imported_func: (arg: number) => {
console.log(`JavaScriptからの挨拶: ${arg}`);
},
},
};
// `importObject`に期待されるインポートを供給してWebAssemblyモジュール`mod`のインスタンスを作成します。
// これは、リクエストごとのインスタンス化を避けるためにスクリプトのトップレベルで行うべきです。
const instance = await WebAssembly.instantiate(mod, importObject);
export default {
async fetch() {
// 引数を使ってWasmインスタンスから`exported_func`を呼び出します。
const retval = instance.exports.exported_func(42);
// 戻り値を返します!
return new Response(`成功: ${retval}`);
},
};

このWorkerが呼び出されると、JavaScriptからの挨拶: 42とログに記録され、成功: 42が返され、JavaScriptからWasmメソッドを引数付きで呼び出す能力を示します。

次のステップ

実際には、Rustなどの選択した言語をWebAssemblyバイナリにコンパイルすることになるでしょう。多くの言語は、JavaScriptとWasmの相互作用を簡素化するためのbindgenを提供しています。これらのツールは、JavaScriptバンドラーと統合され、Wasmモジュールの初期化と呼び出しのためのWebAssembly API以外のAPIを提供することがあります。例として、Rust wasm-bindgenのドキュメントを参照してください。

また、RustでWorker全体を書く場合、Workersはworkers-rsクレートを使用する際に同様のランタイムAPIバインディングを提供します。詳細については、Workers Rustガイドを参照してください。