RustでWebAssemblyに軽く入門した
はじめに
これはあくまで個人的な日々の記録であり備忘録です.WebAssemblyに興味があり,Rustで使えるとのことなので,使ってみました.メモを書き残しておきます.
以下の参考サイトを習っています.
やったのは,"alert"で警告ダイアログのポップアップを出すだけでJavaScriptでも書ける内容ですが,今回はそれをRustで書いたコードから生成されたwasmファイルに処理を書いていて,それをjavascriptから呼び出す感じの処理を書いています.
この記事はあくまで備忘録ですが,以下の手順でメモしています.
環境構築
まず,使ったRustとcargoのバージョンは以下です.共に1.55.0です.以下のようなコマンドで確認できます.
[~] % rustc -V rustc 1.55.0 (c8dfcfe04 2021-09-06) [~] % cargo --version cargo 1.55.0 (32da73ab1 2021-08-23) [~] %
Rustで書いたコードをwasmにコンパイルする,wasm-packが必要らしいです.以下のようにcargo installで入れます.
cargo install wasm-pack
使ってみる
cargo newで"--lib"オプションをつけて,ライブラリ用のターゲットを作ります.cargo newに関するオプションの詳細は公式docから確認可能
名前はhi-wasmにしました(helloじゃなくてhiにしただけで特に意味はないです).
cargo new --lib hi-wasm
wasmにコンパイルされるコードをRustで書く
src/lib.rs
にRustでWebAssemblyで実行するコードを書いてみる.
[~/Code/Project/Project_WebAssembly/hi-wasm] % cat src/lib.rs use wasm_bindgen::prelude::*; #[wasm_bindgen] extern "C" { pub fn alert(s: &str); } #[wasm_bindgen] pub fn greet(name: &str) { alert(&format!("Hi, {}!", name)); }
wasm-bindgenというのが気になったのだけれど,これは"RustとJavascriptの間でやり取りする"ために必要であり,JavascriptからRustで書いたAPI(上記コードでいうgreet)を呼び出せるそうです.
このときのCargo.toml
Cargo.toml
は以下のようにする.
[~/Code/Project/Project_WebAssembly/hi-wasm] % cat Cargo.toml [package] name = "hi-wasm" version = "0.1.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2"
Rustコードをwasmへコンパイルする
wasm-pack build
コマンドで,上記のRustのコード(src/lib.rs)をwasmにコンパイルする.参考サイトにならい,"--target web"オプションをつけた.
[~/Code/Project/Project_WebAssembly/hi-wasm] % wasm-pack build --target web
これを機にwasm-packについて調べた
wasm-packというのを初めて使ったし,"--target web"という書き方がよく分からなかったので調べてみた.公式docを読んで知ったのが以下.
オプション | 使用法(usge) | 説明(description) |
---|---|---|
web | Native in browser(ブラウザネイティブ?) | Outputs JS that can be natively imported as an ES module in a browser, but the WebAssembly must be manually instantiated and loaded. (ESモジュールとしてブラウザにネイティブにインポートできるJSファイルを出力する.ただし,WebAssemblyはマニュアルにインスタンス化されロードされなければならない) |
webオプションは,ブラウザにロードされるJSファイルを出力するという意味らしいです.
ちなみに,wasm-pack buildは以下のようなコマンドらしいです.
The wasm-pack build command creates the files neccessary for JavaScript interoperability and for publishing a package to npm. This involves compiling your code to wasm and generating a pkg folder. This pkg folder will contain the wasm binary, a JS wrapper file, your README, and a package.json file.
「"wasm-pack build"は,Javascriptとの相互運用性に必要なファイル群を作成するためのコマンドであり,また,packageをnpmで配布するためのコマンドです.これはあなたのコードをwasmへとコンパイルし,pkgフォルダを生成します.pkgフォルダはwasmバイナリ,JSラッパーファイル,そしてREADMEとpackage.jsonファイルを含んでいます.」
wasmで書いた処理をjavascriptから呼び出すwebページにアクセスしてみる
参考サイトに習い,index.htmlを作ります.pkg以下にあるhi_wasm.jsをインポートしてます.wasmで書いた処理を呼び出すjsコードみたいに書けそうですね
[~/Code/Project/Project_WebAssembly/hi-wasm] % cat index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>hi-wasm example</title> </head> <body> <script type="module"> import init, {greet} from "./pkg/hi_wasm.js"; init() .then(() => { greet("WebAssembly") }); </script> </body> </html>
webサーバを立ててアクセスする
どこかで見かけた知恵ですが,pythonでwebサーバを立てると,localhost:8000からアクセスできます.
アラートボックス( "Hi WebAssembly"が出たら,ここでは成功です.(普通にjavascriptでも書けそうな処理ですが)
[~/Code/Project/Project_WebAssembly/hi-wasm] % python3 -m http.server
感想と今後の展望
npmは慣れてなかったんだけど,python3でwebサーバを立ててもカジュアルにアクセスできるってことが分かったので,敷居が下がった.
チュートリアルが分かりやすくて学習に助りましたありがとう.こんな感じか,って分かった.使いこなせるようになりたい.本腰入れて公式のドキュメントとかからじっくり読もう
もっと勉強して使いこなせるようになりたいと思った.
参考文献
本記事はこれを実践してました.
wasm-packのコマンドについて気になったので調べるのに見ていました.