TypeScriptとRollupでWebassemblyを稼働させる: Rustが征く(4)
@wasm-tool/rollup-plugin-rustの使い方
関連記事:
Rustが征くシリーズ過去記事
- WSL2で作るWindows開発環境: Rustが征く(1)
- wasmerでWebAssemblyの門を叩く: Rustが征く(2)
- JavaScriptからWebAssemblyの関数を呼び出す: Rustが征く(3)
- TypeScriptとRollupでWebassemblyを稼働させる: Rustが征く(4) ← イマココ
------------------- ↓ 前書はここから ↓-------------------
前回はコマンドを駆使して、
ブラウザ上でWebAssemblyを稼働させるようにした。
ただ、やはりJavaScriptはやはり実用性がないので、
TypeScriptで稼働するようにする。
あと前回は最小行程で稼働させるようにしたのだが、
wasm-packコマンドで丸めて使用する。
バンドルはrollup.jsで一括して稼働するようにしよう。
例によってインストール、プロジェクト作成から行うので、
適当に読み飛ばして欲しい。
------------------- ↓ 本題はここから ↓-------------------
Rustのインストール
以下参照のこと
WSL2で作るWindows開発環境: Rustが征く(1)
必要コマンドを追加
Rustインストールと併せて各種コマンドも追加しておく
rustup target add wasm32-unknown-unknown
cargo install cargo-edit wasm-pack
(・∀・) インストール済みです!
Node.jsのインストール
aptでもbrewでもwingetでもお好きなものをどうぞ
node --version
v16.4.2
npm --version
7.17.0
wasm-packコマンドでプロジェクト作成
wasm-packコマンドでプロジェクトを作成する。
cargo newでも良かったが、
こちらの方が手間が省ける。
名前は何でも良いが console-log
としておこう
wasm-pack new console-log
cd console-log
各種npmパッケージをインストール
TypeScript関連のパッケージをインストール
npm init -y
npm i -D typescript rollup @rollup/plugin-typescript rimraf @wasm-tool/rollup-plugin-rust
npx tsc -t es2021 -m es2020 --allowJs --init
rollup.jsの設定ファイルを作成
rollup.config.mjsを作成する
TypeScriptとWebAssemblyの記述を追加
import typescript from "@rollup/plugin-typescript"
import rust from '@wasm-tool/rollup-plugin-rust'
export default {
input: "./src/main.ts",
output: {
dir: 'dist/js/',
},
plugins:[
typescript(),
rust({
serverPath: "/js/",
}),
]
}
実装作業
TypeScriptの実装作業
フロントエンドプログラム本体。
WebAssemblyを呼び出して、
内包する関数を実行している。
(async () => {
const wasm = await import("../Cargo.toml")
const {say_hello} = await wasm.default()
say_hello("dozo")
})()
Rust側実装作業
前回はalertにはろ~わ~るどだったが、
今回はコンソールに出してみよう。
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
#[wasm_bindgen(js_namespace=console)]
fn log(s: String);
}
#[wasm_bindgen]
pub fn say_hello(message: String) {
log(format!("Hello {} in Rust", message));
}
ビルド開始
cargo buildやwasm packなど個別にコマンドは打たない。
(打っても良いけど)
rollupコマンドだけでビルドを行う
npx rollup -c
index.htmlを用意
最後ににindex.htmlを用意しておく
ファイルを読むだけの簡単なもの
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script type="module" src="./js/main.js"></script>
</head>
<body>
</body>
</html>
Webサーバー起動
サーバーを起動してアクセスしてみる
npx http-server ./dist
F12でコンソールを出してみると
(・∀・) よんだ?
------------------- ↓ 後書はここから ↓-------------------
rollup-wasmプラグインについて
さてWebAssemblyのrollup.jsプラグインだが、
@rollup/plugin-wasm
と@wasm-tool/rollup-plugin-rust
が検索すると出てくる。
正直どちらも微妙だ。
理由はそれぞれ@rollup/plugin-wasm
は普通に動かないこと。
@wasm-tool/rollup-plugin-rust
は余計なお世話機能があることだ。
@rollup/plugin-wasmはよーわからん
何回試しても使う場面が思いつかない。。。
WebAssemblyのrollup.js本家のプラグインに@rollup/plugin-wasm
というのがあるが、
使い方がさっぱりわからない
たぶんemscriptenを使う前提なんだと思う。
wasm-packコマンドで必要なコードも生成されるのだが、
rollup/plugin-wasm
を噛ませると独自解釈のコードに変わって動かなくなる。
@wasm-tool/rollup-plugin-rustはまだ使える
Cargo.tomlをimportしている記述を読み込んでいる箇所を置換するタイプのプラグイン。
ビルドからデプロイまで一括でやってくれるのでまだ使えるが、
個人的にはあまり使いたくない。
importにCargo.tomlって特殊すぎるし、
ファイル名Cargo-xxxx.jsってのが気に入らないなぁ。
@wesley-clements/rollup-plugin-raw-wasm
個人的にはこれを使いたい
理由は 何もしない から。
変な加工とかCargo.tomlをインポートとかヘンテコなことをせず、
.wasmからpathを取り出して後は普通に使える。
import init, {say_hello} from "../pkg/console-log.js"
import path from "../pkg/console-log_bg.wasm"
(async () => {
await init(path)
say_hello("dozo")
})()
設定ファイルは
import { rawWasm } from '@wesley-clements/rollup-plugin-raw-wasm';
export default {
...
plugins: [rawWasm({
publicPath: "./dist/"
})],
...
};
メンテナンス性次第かなぁ。
@wasm-tool/rollup-plugin-rustでビルド時のtypescriptエラー
(Use `node --trace-deprecation ...` to show where the warning was created)
[!] (plugin rpt2) Error: /home/dozo/Repos/Rust/console-log/src/main.ts(1,18): semantic error TS2307: Cannot find module '../Cargo.toml' or its corresponding type declarations.
src/main.ts
Error: /home/dozo/Repos/Rust/console-log/src/main.ts(1,18): semantic error TS2307: Cannot find module '../Cargo.toml' or its corresponding type declarations.
Cargo.tomlが解釈できないというエラー、
その部分を定義しておく必要がある。
以下のファイルを設置する。
declare module "*.toml"
Discussion