Rollupでwasm-bindgenの出力をバンドル

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