Rust で WebAssembly を書いて Deno で実行する
TL;DR
cargo generate --git https://github.com/rustwasm/wasm-pack-template -n myproject
cd myproject
# deno は alert がないので代わりに console.log する
sed -i -e "s/fn alert(s: &str);/#[wasm_bindgen(js_namespace = console, js_name = log)] fn alert(s: \\&str);/" src/lib.rs
wasm-pack build --target web --out-name index
# deno は fetch('file:// ...') をサポートしていない
sed -i -e "s#input = import\\.meta\\.url\\.replace(/\\\\\\.js$/, '_bg\\.wasm');#input = import.meta.url.replace(/\\\\.js$/, '_bg.wasm'); if ('undefined' !== typeof Deno) input = new WebAssembly.Module(await Deno.readFile(new URL(input).pathname));#" pkg/index.js
echo "import * as pkg from './pkg/index.js'
await pkg.default()
pkg.greet()" >| app.ts
deno run --allow-read app.ts
cargo generate --git https://github.com/rustwasm/wasm-pack-template -n myproject
cd myproject
# deno は alert がないので代わりに console.log する
sed -i -e "s/fn alert(s: &str);/#[wasm_bindgen(js_namespace = console, js_name = log)] fn alert(s: \\&str);/" src/lib.rs
wasm-pack build --target web --out-name index
# deno は fetch('file:// ...') をサポートしていない
sed -i -e "s#input = import\\.meta\\.url\\.replace(/\\\\\\.js$/, '_bg\\.wasm');#input = import.meta.url.replace(/\\\\.js$/, '_bg.wasm'); if ('undefined' !== typeof Deno) input = new WebAssembly.Module(await Deno.readFile(new URL(input).pathname));#" pkg/index.js
echo "import * as pkg from './pkg/index.js'
await pkg.default()
pkg.greet()" >| app.ts
deno run --allow-read app.ts
Hello, myproject!
と表示されたら成功です。
プロジェクトの作成
cargo generate --git https://github.com/rustwasm/wasm-pack-template -n myproject
cd myproject
command not found: cargo
cargo generate --git https://github.com/rustwasm/wasm-pack-template -n myproject
cd myproject
command not found: cargo
cargo は Rust 用の便利なコマンドです。
rustup をインストールするとついてきます。
error: no such subcommand: generate
cargo-generate はテンプレートをもとにプロジェクトを初期化(ファイルを作成)してくれます。
今回の場合は https://github.com/rustwasm/wasm-pack-template から src と Cargo.toml をコピペするだけでも代用できます。
Rust を書く
追記 2020/11/12
Deno v1.5.0 で alert が追加されたので、このセクションは飛ばしても大丈夫です
https://github.com/denoland/deno/blob/master/Releases.md#150--20201027
sed -i -e "s/fn alert(s: &str);/#[wasm_bindgen(js_namespace = console, js_name = log)] fn alert(s: \\&str);/" src/lib.rs
追記 2020/11/12
Deno v1.5.0 で alert が追加されたので、このセクションは飛ばしても大丈夫です
https://github.com/denoland/deno/blob/master/Releases.md#150--20201027
sed -i -e "s/fn alert(s: &str);/#[wasm_bindgen(js_namespace = console, js_name = log)] fn alert(s: \\&str);/" src/lib.rs
初期化時点で js の alert を呼び出す処理が書かれていますが
deno に alert はないので代わりに console.log を呼ぶように編集しています。
#[wasm_bindgen]
extern "C" {
- fn alert(s: &str);
+ #[wasm_bindgen(js_namespace = console, js_name = log)] fn alert(s: &str);
}
WebAssembly を作成
wasm-pack build --target web --out-name index
sed -i -e "s#input = import\\.meta\\.url\\.replace(/\\\\\\.js$/, '_bg\\.wasm');#input = import.meta.url.replace(/\\\\.js$/, '_bg.wasm'); if ('undefined' !== typeof Deno) input = new WebAssembly.Module(await Deno.readFile(new URL(input).pathname));#" pkg/index.js
wasm-pack build --target web --out-name index
sed -i -e "s#input = import\\.meta\\.url\\.replace(/\\\\\\.js$/, '_bg\\.wasm');#input = import.meta.url.replace(/\\\\.js$/, '_bg.wasm'); if ('undefined' !== typeof Deno) input = new WebAssembly.Module(await Deno.readFile(new URL(input).pathname));#" pkg/index.js
deno はブラウザとの互換性を重視しています。
将来的には wasm-pack build --target web
だけで問題なく動くようになるのではないかと思います。
現状でも wasm-pack
で作成したライブラリを web サーバーにおけば動くと思うのですが
ローカルで作成・実行までやろうとすると
ローカルのファイルを fetch で取ろうとして( fetch('file:///user/rithmety/myproject/pkg/index_bg.wasm')
)エラーが発生します。
deno が file:// を fetch できるようにする計画はあるようです。
今回はランタイムを直に編集して対応しています。
( Windows だと new URL(input).pathname
の部分が期待通りに動かないかもしれません。 )
async function init(input) {
if (typeof input === 'undefined') {
- input = import.meta.url.replace(/\.js$/, '_bg.wasm');
+ input = import.meta.url.replace(/\.js$/, '_bg.wasm'); if ('undefined' !== typeof Deno) input = new WebAssembly.Module(await Deno.readFile(new URL(input).pathname));
}
command not found: wasm-pack
wasm-pack をインストールしてください。
deno で実行してみる
echo "import * as pkg from './pkg/index.js'
await pkg.default()
pkg.greet()" >| app.ts
deno run --allow-read app.ts
echo "import * as pkg from './pkg/index.js'
await pkg.default()
pkg.greet()" >| app.ts
deno run --allow-read app.ts
deno はトップレベルの await に対応しているのでシンプルに書けます。
import * as pkg from './pkg/index.js'
await pkg.default()
pkg.greet()
Hello, myproject!
と表示されたら成功です。
command not found: deno
deno をインストールしてください。
参考
wasm-pack の公式マニュアル を参考にしました。
Author And Source
この問題について(Rust で WebAssembly を書いて Deno で実行する), 我々は、より多くの情報をここで見つけました https://qiita.com/rithmety/items/30bab6720444f3ad2f3b著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .