JavaScriptからWebAssemblyの関数を呼び出す: Rustが征く(3)
wasm-bindgenをどう使うか
関連記事:
WSL2で作るWindows開発環境: Rustが征く(1)
wasmerでWebAssemblyの門を叩く: Rustが征く(2)
JavaScriptからWebAssemblyの関数を呼び出す: Rustが征く(3)
------------------- ↓ 前書はここから ↓-------------------
Rustネイティブ、WebAssemblyランタイムと来たので、
次はWeb側と接続する。
WebAssemblyはその名前の通りWeb上での使用を前提に設計されているので、
JavaScriptとの接続が容易になっている。
バンドラーは既存のJavaScript用のものを活用する。
パックツールにはwasm-packを使用。
導入部分で一番参考になるのはここかな
これの流れで進めていこう
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 本題はここから ↓-------------------
Rustのインストール
以下参照のこと
WSL2で作るWindows開発環境: Rustが征く(1)
必要コマンドを追加
Rustインストールと併せて各種コマンドも追加しておく
rustup target add wasm32-unknown-unknown
cargo install cargo-edit miniserve wasm-pack
結構時間がかかるので飲み物でも取りに行こう
(-.-)y-~~ 一服してきま~す
cargoコマンドでプロジェクト作成
cargo newにてcargoプロジェクトを作成する
名前は何でも良いが hello-bindgen
としておこう
cargo new --lib hello-bindgen
cd hello-bindgen
Cargo.tomlの修正
生成されたCargo.tomlは内容が不十分なので修正する。
この辺手書きなのがダルい。
ビルドチェックも併せて実行
printf '[lib]\ncrate-type = ["cdylib"]\n' | tee -a ./Cargo.toml
cargo add wasm-bindgen
cargo check --release --target wasm32-unknown-unknown
Cargo.tomlは最終的にはこんな感じ
[package]
name = "hello-bindgen"
version = "0.1.0"
edition = "2018"
# See more keys and their defini・・・・
[dependencies]
wasm-bindgen = "0.2.74"
[lib]
crate-type = ["cdylib"]
src/lib.rs実装
設定が済んだので実装作業開始。
src/lib.rsにデフォルトで記述しているのはテストなので削除して以下に書き換える。
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
pub fn alert(s: &str);
}
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
(・∀・) 実装完了
ビルド開始
cargo build --release --target wasm32-unknown-unknown
wasm-pack build --release --target web -d ./dist/js
index.htmlを用意
最後ににindex.htmlを用意しておく
Rust側で設置したgreet関数をJS側から呼び出す
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script type="module">
import init, { greet } from './js/hello_bindgen.js';
(async () => {
await init()
greet('Bindgen')
})()
</script>
</body>
</html>
Webサーバー起動
Webサーバーを起動してアクセスしてみよう
miniserve ./dist
(^_^)b はろ~
------------------- ↓ 後書はここから ↓-------------------
設定項目を整理
今回、最小行程ではろ~わ~るどするために、
コマンドが長くなったり、
Node.jsを使わなかったりしたが、
いろいろ不便な部分が出てしまう。
なので、設定項目を調整しよう
ビルドターゲットの固定化
毎回--target=wasm32-unknown-unknown
って打つのは長くなるので短くしたい。
targetを変更することはほぼないので固定化しておこう。
./.cargo/config.toml
というファイルを作成して、
ターゲットを記述する。
cd /path/to/hello-bindgen
mkdir .cargo
printf '[build]\ntarget = "wasm32-unknown-unknown"\n' | tee .cargo/config.toml
cargo clean
cargo check --release
wasm-packでビルドするとwasm32-unknown固定になるっぽい
ツールチェインの固定化
ツールチェイン指定でnightly使ってねっていうのが稀に良くある。
コマンドラインでやると手間なので、
こちらも固定化したい。
以下のようにnightlyを追加して一覧を見ると
rustup toolchain add nightly
rustup component add rust-src
rustup toolchain list
stable-x86_64-unknown-linux-gnu (default)
nightly-x86_64-unknown-linux-gnu
では設定を追加して実行してみる。
./rust-toolchain.toml
を作成し、
ツールチェインを設定する。
printf '[toolchain]\nchannel = "nightly"' | tee rust-toolchain.toml
rustup toolchain list
stable-x86_64-unknown-linux-gnu (default)
nightly-x86_64-unknown-linux-gnu (override)
(override)
と上書きされていることがわかる
🤔Rustの設定ファイルってとっ散らかり過ぎじゃね?
rollup.jsでビルド行程をまとめようかと思ったけど、
長くなったのでそれは別の機会に。
謎のエラー
Uncaught TypeError: Failed to resolve module specifier "wasm_thread.js". Relative references must start with either "/", "./", or "../".
🤔ナニコレ?
WebAssembly関連ファイルのパス指定をファイル名だけにしたときに発生。
なんか、相対パス的に書けとのこと。
- import init from 'hello_bindgen.js';
+ import init from './hello_bindgen.js';
理由?
セキュリティてきなさむしんぐやろ。
しらんけど。
Discussion