RustでWeb向けのWebAssemblyを開発するためのデファクトツールはwasm-bindgenです。Javascriptとのオブジェクト受け渡しインターフェースを実装したJavascriptラッパー+TypeScript型を出力します。
基本的にはwasm-bindgenが出力したJavascriptをimportしてWebAssemblyの関数を呼び出すようにすべきです。ただし、rollupでバンドルする際、以下の問題があり工夫が必要です。
- wasmのプライベート変数をrollupが参照できず、
undefined
に置き換えられる
wasm-bindgenはいくつかの出力形式をサポートしており、web
の形式で出力すると、たまたまrollupにプライベート変数を消されないコードを出力できます。
$ wasm-bindegen --target web --out-dir dist/ input.wasm
ただし、
webモードはwasmをロードしないため、アプリケーション内にロード処理を追加する必要があります。
Without a Bundlerに解説があり、init()
というデフォルト関数をimportしてあらかじめ呼び出すことで、wasmの関数をセットアップできます。
Javascriptの参照関係については今のところ、これ以外の手段はなさそうです。
また、wasmバイナリについては別途デプロイが必要です。
まず、wasmをビルド時に読み飛ばすために、
@rollup/plugin-wasmが必要です。これはrollupの一般的なプラグインと使い型は変わらず、インストールのうえpluginのリストにwasm()
を追加するだけです。
ただし、出力にwasmをコピーしないため、手動でwasm-bindgenが出力したバイナリをコピーする必要があります。なお、バンドルされたJSがsome-bundle.js
の場合、some-bundle_bg.wasm
というファイル名で参照するため、あわせてリネームも必要です。
このように、Rollupでwasm-bindgenの出力をバンドルする際には注意が必要です。別の方式としては、バンドル過程でcargo buildを連続的に実行する rollup-plugin-rustもあります。こちらはCargo.tomlをimportするだけで適切な出力が可能ですが、ビルドプロセスが連結してしまうため一長一短です。
Chuma Takahiro