以前 Rust をはじめてみよう!という記事を書いた。今回は Rust + WebAssembly を使って Hello, World! の出力をやってみた。
WebAssembly について
まず WebAssembly とは何か。本家サイトの Overview をみてみる。ここにある通り、WebAssembly(WASM)は C/C++/Rust などの高級言語を使って開発をしバイナリ形式で動かすことができる。その為 Web 上で高速に動かすことができる。とりわけゲームなどの実行速度が求められるような分野で有効になる。Chrome、Firefox、Safari、Edgeで利用が可能。
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.https://webassembly.org/
よくデモに出てくる Unity を使った動画
Youtube動画
再生回数が一番多い動画をあげておく。2018年2月の動画ですごく分かりやすく説明されている。
Rust+WebAssembly のドキュメント
ここからは以下の記事を実際にやってみる。実際にほぼそのまま実行しているだけなので以下についてはリンクをチェックするだけでも良いです。
事前準備
rustup を使って rust をインストールする
curl https://sh.rustup.rs -sSf | sh
source $HOME/.cargo/env
source $HOME/.cargo/env
は .zshrc などに記述しておくとよい
wasm-pack インストール
wasm-pack を使うとビルド・テスト・公開などが簡単にできる
$ curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
cargo-generate インストール
cargo-generate を入れるとcargo generate
コマンドが使えるようになり、この後の Git リポジトリからのソース取得ができる
$ cargo install cargo-generate
npm インストール
最新の npm を入れておく
$ npm install npm@latest -g
サンプルプロジェクトのテンプレート
Hello, World!
のサンプルプロジェクトを取得する
$ cargo generate --git https://github.com/rustwasm/wasm-pack-template
// プロジェクト名を聞かれるのでここはドキュメントの通り`wasm-game-of-life`とする
ドキュメントツリーは以下のようになる。ドキュメントにはないtests
が追加されていた。ここでsrc/lib.rs
のgreet
関数の文字列が、Hello, wasm-game-of-life!
となっているので一応Hello, World!
と変えておく。
wasm-game-of-life
├── Cargo.toml
├── LICENSE_APACHE
├── LICENSE_MIT
├── README.md
├── src
│ ├── lib.rs
│ └── utils.rs
└── tests
└── web.rs
wasm-pack
コマンドでビルドしてみる。rustcのバージョンが1.30以上でないとエラーが発生するけどrustup update
コマンドでアップデートすれば問題なく進められる。
$ wasm-pack build
| [1/9] Checking `rustc` version...
Your version of Rust, '1.29', is not supported. Please install Rust version 1.30.0 or higher.
rustup
を使ってrustc
をアップデートする
$ rustup update
ビルドが完了するとpkg
ディレクトリができる
wasm-pack build
pkg
├── README.md
├── package.json
├── wasm_game_of_life.d.ts
├── wasm_game_of_life.js
└── wasm_game_of_life_bg.wasm
Webページを作成する為に以下のコマンドを実行する。するとあらたにwww
ディレクトリができる。
$ npm init wasm-app www
npx: 1個のパッケージを3.137秒でインストールしました。
Rust + Wasm = ❤
www
のドキュメントツリー
www
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── bootstrap.js
├── index.html
├── index.js
├── package-lock.json
├── package.json
└── webpack.config.js
www
ディレクトリへ移動し依存関係をインストールする
$ npm install
pkg
ディレクトリへ移動し以下のコマンドを実行する
$ npm link
/usr/local/lib/node_modules/wasm-game-of-life -> /Users/satomasaki/Dev/taisa/wasm-game-of-life/pkg
更にwww
ディレクトリへ移動して以下のコマンドを実行する
$ npm link wasm-game-of-life
/Users/satomasaki/Dev/taisa/wasm-game-of-life/www/node_modules/wasm-game-of-life -> /usr/local/lib/node_modules/wasm-game-of-life -> /Users/satomasaki/Dev/taisa/wasm-game-of-life/pkg
index.js
のimport
箇所のhello-wasm-pack
をwasm-game-of-life
に更新する
import * as wasm from "wasm-game-of-life";
wasm.greet();
実行しページを開いてみるとHello, World!
が表示される。
$ npm run start
ソースを少し変更してみる
wasm-game-of-life/src/lib.rs
のgreet
関数を以下のように少し変更しwasm-game-of-life/www/index.js
のgreet
関数の引数に文字列を入れてみると渡した文字列が出力される
$ [wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
wasm.greet("wasm!");
Webサーバを立ち上げたままでもwasm-pack build
と実行するだけでソースが更新され動作確認をすることができる。
まとめ
本当に少し触っただけながら、便利なツールがちゃんとあって、ある程度形ができて慣れてくればそれほどストレスなく開発が進められそう。