SvelteでWebAssemblyでTypeScriptでRollupで: Rustが征く(5)
要素多過ぎ問題
関連記事:
Rustが征くシリーズ過去記事
- WSL2で作るWindows開発環境: Rustが征く(1)
- wasmerでWebAssemblyの門を叩く: Rustが征く(2)
- JavaScriptからWebAssemblyの関数を呼び出す: Rustが征く(3)
- TypeScriptとRollupでWebassemblyを稼働させる: Rustが征く(4)
- SvelteでWebAssemblyでTypeScriptでRollupで: Rustが征く(5) ← イマココ
前回の記事でTypeScriptとrollup.js、WebAssemblyを繋いだ。
次はフロンドエンドフレームワークと繋いでみよう。
フロントエンドはYewって手もあったが、
ちまちま調整が必要なフロントエンドと、
ちょっと動かすだけでも大変なRustは相性が悪い。
なのでJavaScriptフレームワークを選択。
けど、VueやReactはもううんざりなので、
最近話題のSvelteを使う。
Svelte is a tool for building fast web applications.
It is similar to JavaScript frameworks such as React and Vue, which share a goal of making it easy to build slick interactive user interfaces.
But there's a crucial difference: Svelte converts your app into ideal JavaScript at build time, rather than interpreting your application code at run time. This means you don't pay the performance cost of the framework's abstractions, and you don't incur a penalty when your app first loads.
You can build your entire app with Svelte, or you can add it incrementally to an existing codebase. You can also ship components as standalone packages that work anywhere, without the overhead of a dependency on a conventional framework.
Svelte
VueからVirtual DOMの概念を撤去したもの。
コード量は他の二つに比べて少なくなるとのこと。
一から記述すると本編が長くなりすぎるので、
今回はテンプレートを使用する。
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 本題はここから ↓-------------------
事前準備
Rust, Node.jsが稼働することが前提。
過去記事を参照のこと
以下のコマンドが実行できればOk。
cargo --version
npm --verion
rustup target add wasm32-unknown-unknown
cargo install cargo-edit
Svelteのテンプレートからプロジェクトを作成
Svelteのビルドをrollup.jsで実行するテンプレートを使用する
デフォルトではJavaScriptで構成されているのだが、
TypeScriptに置換するスクリプトが用意されている。
使用するパッケージのバージョンも古いので、
それらを新しいものに設定し直す。
npx degit sveltejs/template svelte-wasm
cd svelte-wasm
node ./scripts/setupTypeScript.js
npx npm-check-updates -u
npm i -D @wesley-clements/rollup-plugin-raw-wasm
npm run dev
(・∀・) 簡単ですね!!
rollup.jsの設定を調整
WebAssemblyをビルドする前にrollup.jsの設定を調整しておく。
npmでインストールしたwasmローダーを設定に加える。
import css from 'rollup-plugin-css-only';
+ import { rawWasm } from "@wesley-clements/rollup-plugin-raw-wasm"
const production = !process.env.ROLLUP_WATCH;
・・・
typescript({
sourceMap: !production,
inlineSources: !production
}),
+ rawWasm({
+ publicPath: '/build/'
+ }),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
WebAssemblyモジュールを用意
cargoコマンドでRustのソースを設置する
cargo init --lib
printf '[lib]\ncrate-type = ["cdylib", "rlib"]' | tee -a ./Cargo.toml
cargo add wasm-bindgen js-sys
実装
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn sum_numbers(numbers: &[i32]) -> i32 {
numbers.iter().sum()
}
ビルド
wasm-pack build --target web --release --out-name svelte-wasm
Svelte側にWebAssemblyを実装
ソースコード
WebAssemblyは基本的に非同期処理で呼び出す必要があるので、
全体的に非同期に変えておく。
import App from './App.svelte'
import init, {sum_numbers} from "../pkg/svelte-wasm.js"
import path from "../pkg/svelte-wasm_bg.wasm"
const app = (async () => {
await init(path)
const app = new App({
target: document.body,
props: {
name: 'world',
sum_numbers,
}
})
})()
export default app;
ビュー側
<script lang="ts">
export let name: string;
+ export let sum_numbers: Function;
+ const sum = sum_numbers(new Int32Array([5,60,300]))
</script>
<main>
- <h1>Hello {name}!</h1>
+ <h1>Hello {name} {sum}!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
</main>
実行
npm run dev
(・∀・)(・∀・)Yeah!!!!
フロントエンドの構成が固まった。
------------------- ↓ 後書はここから ↓-------------------
esbuild使わないの?
時系列ではこちらの記事が先だったが、
以下の記事を先に公開している。
要素が増えすぎると煩雑になるので、
この記事ではesbuildに関する記述は抜いた。
Discussion