Web Worker+WASM+Parcel+TypeScriptでマルチスレッド実行: Rustが征く(12)
Viteで行きたかったがParcelで我慢
関連記事:
Rustが征くシリーズ過去記事
- WSL2で作るWindows開発環境: Rustが征く(1)
- wasmerでWebAssemblyの門を叩く: Rustが征く(2)
- JavaScriptからWebAssemblyの関数を呼び出す: Rustが征く(3)
- TypeScriptとRollupでWebassemblyを稼働させる: Rustが征く(4)
- SvelteでWebAssemblyでTypeScriptでRollupで: Rustが征く(5)
- WASMのサイズでかすぎね?: Rustが征く(6)
- Webassemblyマルチスレッド用crateを調べる: Rustが征く(7)
- WebAssemblyでSleep: Rustが征く(8)
- Web Workerでマルチスレッド(JSのみ): Rustが征く(9)
- Web Worker+WebAssemblyでマルチスレッド: Rustが征く(10)
- Web Worker+WebAssemblyのパフォーマンス計測: Rustが征く(11)
- Web Worker+WASM+Parcel+TypeScriptでマルチスレッド実行: Rustが征く(12) ← イマココ
さらに要素多過ぎ問題
------------------- ↓ 前書はここから ↓-------------------
以前の記事
Web Worker+WebAssemblyのパフォーマンス計測: Rustが征く(11)にて、
WebAssemblyマルチスレッドをESモジュールで実行するのが確認できた。
となれば、バンドラーと組み合わせることができるかもしれない。
ということで、今回はバンドラーParcelを使用して、
マルチスレッド実行環境を作ってみる。
他のバンドラーではうまくいかなかったのよねぇ。
Viteはjs上でWorkerロードできなかった。
rollup.jsは後書きで
あと、TypeScriptはデフォルトで使っちゃおう。
もう、素のJS使う人なんておらんやろ。
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 本題はここから ↓-------------------
RustとNode.jsのインストール
過去記事を参考のこと
以下のコマンドが動くようにしておく
node --version
v16.4.2
npm --version
7.17.0
cargo --version
cargo 1.54.0 (5ae8d74b3 2021-06-22)
cargoとnpmコマンドでプロジェクト作成
cargo newにてcargoプロジェクトを作成する
今回はいろいろ省略するためにwasm-packデフォルトテンプレートを使用
cargo install cargo-edit wasm-pack wasm-bindgen-cli
wasm-pack new parcel-worker
cd parcel-worker
npm init -y
npm i -D parcel rimraf http-server typescript @parcel/transformer-typescript-tsc @parcel/validator-typescript
npx tsc -t ES2021 -m ES2020 --allowJs --init
wasm-pack build --release --target web --out-name parcel-worker
Parcelの設定を調整
設定不要が売りのParcelだが、
TypeScript使うときは内容を調整した方が使いやすい。
{
"extends": "@parcel/config-default",
"transformers": {
"*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
},
"validators": {
"*.{ts,tsx}": ["@parcel/validator-typescript"]
}
}
package.jsonも調整
- "main": "index.js",
メインスレッドを設置
スレッドを二つ生成してwasmを実行する
(async () => {
const path = new URL('./worker.ts', import.meta.url)
let worker = []
for(let i = 0; i < 2; i++) {
worker[i] = new Worker(path, {type:"module"});
}
})();
worker側を設置
JS-wasm間で文字列と配列のやり取りできるか確認する
import init, {greet, sum_numbers} from '../pkg/parcel-worker.js'
(async () => {
await init()
console.log(greet("dozo"))
console.log(sum_numbers(new Int32Array([5,60,300])))
})()
フロントエンドを用意
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title>My awesome Rust, WebAssembly, and Parcel application</title>
<script type="module" src="./src/index.ts"></script>
</head>
<body>
</body>
</html>
実装してビルド
今回は文字列の取得と、配列の合計を取得
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn sum_numbers(slice: &[i32]) -> i32 {
slice.iter().sum()
}
#[wasm_bindgen]
pub fn greet(s: &str) -> String {
format!("Hello {}!", s)
}
ビルド開始
wasm-pack build --release --target web --out-name parcel-worker
npx parcel serve ./index.html
http://localhost:1234 にアクセス
console.logに以下の文字列がでてるはず
Hello dozo!
worker.ts:6 365
サーバー起動
npx http-server ./dist
http://172.21.150.239:8080 にアクセス
スレッドの確認
メインスレッドとは別に二つスレッドが立っていることがわかる
スレッド
結果の確認
文字列、計算ともにやり取りができていることがわかる
(^_^;) やっとベースができたか
10回以上hello world記事を書いているわけだが、
漸くベースが出来上がった気がする。
------------------- ↓ 後書はここから ↓-------------------
ビルドターゲット"no-modules"は?
手動でデプロイディレクトリに置くのなら可能かもだが、
ビルドシステムに載せるのは無理っぽい。
rollup.jsなら?
Parcelだと最小行程でいけるけど、
ビルド後の挙動が不安定な感じがする。
(Parcel serveコマンドだと安定するんだけどね)
rollup.jsで行きたいところだが、
ビルド環境を構築できずにいる。
確立した時点で別記事にするかも。
SyntaxError: Unexpected token 'export' エラー
普通にビルドすると以下のエラーが出た
❯ npx parcel watch ./index.html --no-cache
🚨 Build failed.
Error: Unexpected token 'export'
/home/dozo/Repos/parcel-worker/node_modules/@parcel/ts-utils/src/index.js:2
export * from './FSHost';
^^^^^^
SyntaxError: Unexpected token 'export'
SyntaxError: Unexpected token 'export' エラー全文
❯ npx parcel watch ./index.html --no-cache
🚨 Build failed.
Error: Unexpected token 'export'
/home/dozo/Repos/parcel-worker/node_modules/@parcel/ts-utils/src/index.js:2
export * from './FSHost';
^^^^^^
SyntaxError: Unexpected token 'export'
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
at Module._compile (node:internal/modules/cjs/loader:1065:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at NodePackageManager.load (/home/dozo/Repos/parcel-worker/node_modules/@parcel/package-manager/lib/NodePackageManager.js:163:9)
at NodePackageManager.requireSync (/home/dozo/Repos/parcel-worker/node_modules/@parcel/package-manager/lib/NodePackageManager.js:129:17)
at Module.m.require (/home/dozo/Repos/parcel-worker/node_modules/@parcel/package-manager/lib/NodePackageManager.js:149:19)
at require (node:internal/modules/cjs/helpers:94:18)
at Object.<anonymous> (/home/dozo/Repos/parcel-worker/node_modules/@parcel/transformer-typescript-tsc/lib/TSCTransformer.js:10:16)
@parcel/transformer-typescript-tsc
にバグがあったようで、
2.0.0-alpha.3
の段階で発生
nightlyでは修正済みとあるので、
次のバージョンである 2.0.0-rc.0
では修正されている
(stableの段階では考えなくてもいい)
https://github.com/parcel-bundler/parcel/issues/4627
以下のコマンドでバージョンアップしておく
npm i -D @parcel/transformer-typescript-tsc@next @parcel/validator-typescript@next
Discussion