wasm-packのターゲットをno-moduleにしたときの利用法
マルチスレッドとかでは重要だったりするが
関連記事:
Rustが征くシリーズ過去記事
- WSL2で作るWindows開発環境: Rustが征く(1)
- wasmerでWebAssemblyの門を叩く: Rustが征く(2)
- JavaScriptからWebAssemblyの関数を呼び出す: Rustが征く(3)
- TypeScriptとRollupでWebassemblyを稼働させる: Rustが征く(4)
- SvelteでWebAssemblyでTypeScriptでRollupで: Rustが征く(5)
- WASMのサイズでかすぎね?: Rustが征く(6)
- Webassemblyマルチスレッド用crateを調べる: Rustが征く(7)
- WebAssemblyでSleep: Rustが征く(8)
wasm-packのビルドオプションにtargetというのがある。
ここで選択できるオプションに
- nodejs
- bundler(webpack)
- deno
- web
- no-module
というのがある。
nodejs
, bundler
, deno
は言うまでも無いが、
webとno-moduleで生成されるWebAssemblyモジュールは同じもの
(チェックサムも一致する)
となると生成されるjsファイルが異なるのだが、
どう使い分けるのかというのが今回の話。
targetを整理すると
taret | generated |
---|---|
nodejs | commonjs |
deno | for deno |
bundler | webpack |
no-module | iife |
web | ES Module |
という感じか。
iifeとは即時実行関数のことで、
ファイルをロードすると wasm-bindgen
というグローバル変数が取得できる
ES Moduleはimport/exportのES6フォーマットのこと。
以下に書いた記事
[JavaScriptからWebAssembly関数を呼び出す: Rustのすゝめ(3)]
ではtarget=webの場合の内容なので、
今回はno-moduleの場合を記述する。
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 本題はここから ↓-------------------
cargoコマンドでプロジェクト作成
cargo newにてcargoプロジェクトを作成する
今回はいろいろ省略するためにwasm-packデフォルトテンプレートを使用
cargo install cargo-edit wasm-pack wasm-bindgen-cli miniserve
wasm-pack new hello-nomodule
cd hello-nomodule
ビルド開始
wasm-pack build --release --target no-modules -d ./dist/js
index.htmlを用意
最後ににindex.htmlを用意しておく
Rust側で設置したgreet関数をJS側から呼び出す
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script src="./js/hello_nomodule.js"></script>
<script type="module">
(async () => {
const {greet} = await wasm_bindgen('./js/hello_nomodule_bg.wasm')
greet()
})()
</script>
</body>
</html>
Webサーバー起動
Webサーバーを起動してアクセスしてみよう
miniserve ./dist
------------------- ↓ 後書きはここから ↓-------------------
結果は前回の記事とだいたい同じだが、
HTMLでの使い方が少し違う
(greet関数の使い方は本筋じゃないのでスルーで)
<script type="module">
import init, { greet } from './js/hello_bindgen.js';
(async () => {
await init()
greet('Bindgen')
})()
</script>
<script src="./js/hello_nomodule.js"></script>
<script type="module">
(async () => {
const {greet} = await wasm_bindgen('./js/hello_nomodule_bg.wasm')
greet()
})()
</script>
(・ω・) wasm_bindgen
って変数はどっから来た?
上記で述べたように no-modules
=iifeなので、
js/hello_nomodule.js
を読み込んだ時点で生成されている。
HTML上で使う分にはこれでいいのだが、
JavaScript上で呼び出そうとすると生成されたものをそのまま使おうとするとちょっと扱いづらい。
なので、no-module版のjsファイルの最終行に以下を追加する
+ export default wasm_bindgen
ビルドコマンドは以下のような感じか。
wasm-pack build --release --target no-modules -d ./dist/js
printf '\nexport default wasm_bindgen\n' | tee -a ./dist/js/hello_nomodule.js
Discussion