チートシート

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] アトリビュート

用途RustJavaScript
関数をエクスポート#[wasm_bindgen] pub fn foo()foo()
構造体をクラスに#[wasm_bindgen] pub struct Foonew 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)]非公開

型マッピング

RustJSコスト
i32, f64, boolnumber, boolean無料
i64, u64BigInt無料
&strstring (JS→Rust)コピー
Stringstring (Rust→JS)コピー
Vec<u8>, &[u8]Uint8Arrayコピー
Vec<f64>Float64Arrayコピー
JsValueany参照
Option<T>T | undefined可変
Result<T, JsValue>T (Errでスロー)可変
#[wasm_bindgen] structclassポインタ
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で構造化データを渡さない — フラット配列を使う