🦀

Rust 🦀 and WebAssemblyのチュートリアルを読む

2022/12/12に公開

Rust 🦀 と Wasm の "Hello, World!"

本記事は、筆者がRustとWasmを学ぶために以下のドキュメントを読み進めた過程を記すものです。 最終的にライフゲームの完成を目指しますが、とりあえず今回はHello,World!までです。
https://rustwasm.github.io/docs/book/introduction.html#rust--and-webassembly-

RustとWasm

Rust

2022年現在とても人気のある言語。あらゆるLinuxコマンドのオルタナティヴの多くがRustで書かれている印象を受けます。いろいろ良い点があるが本筋ではないので省略、というより詳しくは知りません。

Wasm

WebAssembly。ウェブブラウザを含むあらゆる環境内で実行できるプログラミング言語。とても注目されています。よく見るサンプルがRustで書かれたプログラムをWasmにコンパイルしてブラウザで実行する。この記事でもそれをします。

セットアップ

用意するもの

Rustの基本的なツールチェイン

rustup,rustc,cargo

wasm-pack

cargo install wasm-pack

cargo-generate

cargo install wasm-pack

参考記事
https://github.com/rustwasm/wasm-pack/issues/952#issuecomment-792838226

npm

パッケージマネージャ等を使ってインストール。もし既にインストールされている場合は最新版にアップデートする。

npm install npm@latest -g

私はバージョンマネージャーにvoltaを使っているので、それでバージョンを切り替えました。

volta install node@latest

Hello, World!

Rust&Wasmのプロジェクトテンプレートが用意されているので活用します。プロジェクト名が聞かれるので好きな名前を入力する。今回はチュートリアルに従ってwasm-game-of-life

cargo generate --git https://github.com/rustwasm/wasm-pack-template
cd wasm-game-of-life

構成ファイル

Cargo.toml

依存関係やメタデータを指定するファイル。

lib.rs

WebAssemblyにコンパイルするRustクレートのルートファイル。

utils.rs

wasmにコンパイルされたRustを使いやすくするためのユーティリティを提供するファイル。

プロジェクトをビルドする

wasm-pack build

ビルドで出力されたファイル。

wasm_game_of_life_bg.wasm

.wasmは、RustソースからコンパイルされてたWebAssemblyのバイナリファイル。

wasm_game_of_life.js

.jsは、wasm-bindgenによって生成され、DOMとJS関数をRustにインポートし、Wasm関数のAPIをJSに公開するためのJSグルーが含まれているファイル。

wasm_game_of_life.d.ts

.d.tsは、JSのグルーのためのTSの方宣言が含まれているファイル。

package.json

生成されてJSとWasmパッケージに関するメタデータが含まれている。npmを使ったプロジェクトで生成されるpackage.jsonと同じ。

Webページに落とし込む

npm init wasm-app www

🦀 Rust + 🕸 Wasm = ❤

www/package.json

webpackとwebpack-dev-serverとの依存関係、npmに公開されているhello-wasm-packの依存関係が事前に設定されている。

www/webpack.config.js

webpackとローカル開発サーバの設定ファイル。特にいじる必要はない。

www/index.html

Webページのルートとなるhtmlファイル。

www/index.html

Webページで使うJSのエントリーポイント。

依存関係のインストール

cd www
npm install

ローカルのwasmパッケージ(wasm-game-of-life)を使うように、package.jsonに依存関係を追加する。

 "dependencies": { "wasm-game-of-life": "file:../pkg" },

index.jsを編集して、wasm-game-of-lifeをインポートするようにさせる。

import * as wasm from "wasm-game-of-life";

wasm.greet();

新しい依存関係をインストール

npm install

ローカルで動かす

npm run start

エラーが発生

ERR_OSSL_EVP_UNSUPPORTED

OpenSSL 3.0関連のエラーの模様。対処策として次のようにすると解消されます。

export NODE_OPTIONS=--openssl-legacy-provider

参考文献
https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V17.md#openssl-30
https://zenn.dev/yogarasu/articles/425732ff408d06

練習問題

greet関数が引数を受け取れるように変更し、自分の名前が表示されるように変更する。

pub fn greet(name: &str) {
 alert(&format!("Hello, {}!", name));
}
wasm.greet("k41531");

Discussion