チートシート
Rust + WebAssembly開発のクイックリファレンス
プロジェクトセットアップ
Cargo.toml
[lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2" web-sys = { version = "0.3", features = ["Window", "Document"] } js-sys = "0.3" wasm-bindgen-futures = "0.4"
Terminal
# Install cargo install wasm-pack # Build wasm-pack build --target web # Build for bundler (Webpack, Vite) wasm-pack build --target bundler
#[wasm_bindgen] アトリビュート
| 用途 | Rust | JavaScript |
|---|---|---|
| 関数をエクスポート | #[wasm_bindgen] pub fn foo() | foo() |
| 構造体をクラスに | #[wasm_bindgen] pub struct Foo | new Foo() |
| コンストラクタ | #[wasm_bindgen(constructor)] | new Foo() |
| ゲッター | #[wasm_bindgen(getter)] | obj.name |
| セッター | #[wasm_bindgen(setter)] | obj.name = x |
| JS関数をインポート | extern "C" { fn alert(s: &str); } | window.alert() |
| JS名前空間 | #[wasm_bindgen(js_namespace = console)] | console.log() |
| リネーム | #[wasm_bindgen(js_name = "myFunc")] | myFunc() |
| エクスポートしない | #[wasm_bindgen(skip)] | 非公開 |
型マッピング
| Rust | JS | コスト |
|---|---|---|
i32, f64, bool | number, boolean | 無料 |
i64, u64 | BigInt | 無料 |
&str | string (JS→Rust) | コピー |
String | string (Rust→JS) | コピー |
Vec<u8>, &[u8] | Uint8Array | コピー |
Vec<f64> | Float64Array | コピー |
JsValue | any | 参照 |
Option<T> | T | undefined | 可変 |
Result<T, JsValue> | T (Errでスロー) | 可変 |
#[wasm_bindgen] struct | class | ポインタ |
Closure<dyn FnMut()> | Function | メモリ確保 |
よく使うパターン
関数エクスポート
#[wasm_bindgen] pub fn add(a: i32, b: i32) -> i32 { a + b }
JS呼び出し
import init, { add } from './pkg/my_wasm.js'; await init(); add(2, 3); // → 5
console.logのインポート
#[wasm_bindgen] extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); }
エラーハンドリング
#[wasm_bindgen] pub fn run() -> Result<(), JsValue> { // ? converts Err to JS exception let el = document.create_element("div")?; Ok(()) }
よく使うweb-sysフィーチャー
WindowDocumentElementHtmlElementHtmlCanvasElementCanvasRenderingContext2dconsoleNodeStorageMouseEventKeyboardEventRequestRequestInitResponseHeadersUrlHistoryLocation
パフォーマンスのヒント
- ✓ プリミティブ(i32, f64, bool)を優先 — ゼロコスト
- ✓ フラット配列(Vec<f64>)で大量データを転送
- ✓ バッファを再利用 — フレームごとにVecを確保しない
- ✓ 構造体はポインタ渡し — データコピーなし
- ✗ 文字列の頻繁な受け渡しを避ける — 毎回コピーが発生
- ✗ JSON.stringifyで構造化データを渡さない — フラット配列を使う