Rust / WebAssembly 開発メモ

開発方法について

wasm-packのインストール

cargo install wasm-pack

プロジェクトの作成

  • プロジェクトを作成する。例としてプロジェクト名をhello-wasmとする。
    -lib オプションでライブラリ用のプロジェクトになる。
cargo new --lib hello-wasm
  • hello-wasmフォルダが作成されるので、このフォルダをVSCodeで開く。
  • Cargo.toml を例えば下記のように書き換える。
[package]
name = "hello-wasm"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
description = "A sample project with wasm-pack"
license = "MIT/Apache-2.0"
repository = "https://github.com/ユーザ名/hello-wasm"
edition = "2018"

[lib]
crate-type = ["cdylib"]  # 他言語からロードされる動的ライブラリをビルド

[dependencies]
wasm-bindgen = "0.2" # JavaScriptとRustをつなぐwasm-bindgenクレートに依存
  • src/lib.rs を例えば下記のように書き換える。
use wasm_bindgen::prelude::*;  // JavaScriptとRustをつなぐwasm-bindgenクレートを使用

// Rustから呼び出すJavaScript関数を宣言
#[wasm_bindgen]
extern {
    pub fn alert(s: &str);
}

// JavaScriptから呼び出すRust関数を定義
#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}
  • index.html を (プロジェクトのフォルダ直下に) 作成し、例えば下記のように書く。
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>hello-wasm example</title>
  </head>
  <body>
    <script type="module">
      //WebAssemblyとのつなぎのJavaScriptをインポート
      import init, { greet } from "./pkg/hello_wasm.js";

      // WebAssemblyモジュールを初期化
      init().then(() => {

        // Rust で書いた greet 関数を呼び出す
        greet("WebAssembly");
      });
    </script>
  </body>
</html>

ビルド

  • プロジェクトをビルドする。
wasm-pack build --target web
  • プロジェクトの主なファイルは下図のような構成になる。
┣ Cargo.toml   Rustプロジェクトの設定
┣ index.html   HTML
┣ src
┃ ┗ lib.rs     Rustのソース
┣ target/      Rustのビルド出力
┗ pkg/         デプロイすべきファイル (wasm や js)

動作確認

  • 動作確認のためにはWebサーバーでホストする必要があるが、VSCode拡張機能である Live Server を利用すればワンクリックでWebサーバーが起動して自動的にブラウザを開いてくれる。
    VSCodeで簡単ローカルWebサーバ - 滴了庵日録
  • ダイアログに「Hello, WebAssembly!」と表示されれば、上記のコードの動作確認OK。

VSCodeでのデバッグ

  • VSCode拡張機能 WebAssembly DWARF Debugging をインストールする。
  • Cargo.toml に追記。
[package.metadata.wasm-pack.profile.dev.wasm-bindgen]
dwarf-debug-info = true
  • ビルドする。(--dev オプションを付ける)
wasm-pack build --target web --dev
  • .vscode/launch.json を作成する。(このファイルは、VSCodeで Cargo.toml を開いた状態で左端のデバッグボタン→「create a launch.json file」→「Web App (Chrome)」から自動生成できるが、"url" のポート番号を環境に合わせて修正する。デフォルトは 8080 だが、Live Serverの場合は 5500 になる。また必要に応じてトップページのURLを明示する。(下記の例では /index.html )

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome against localhost",
            "url": "http://localhost:5500/index.html",
            "webRoot": "${workspaceFolder}"
        }
    ]
}

  • 初回のブラウザ起動ではブレークポイントが反応しないことがあるので、その場合はブラウザをリロード。

参考