iTranslated by AI
Using Svelte, WebAssembly, TypeScript, and Rollup: The Rust Journey (5)
The Problem of Too Many Elements
Related Articles:
Past Articles in the "Rust Conquers" Series
- Building a Windows Development Environment with WSL2: Rust Conquers (1)
- Knocking on the Door of WebAssembly with wasmer: Rust Conquers (2)
- Calling WebAssembly Functions from JavaScript: Rust Conquers (3)
- Running WebAssembly with TypeScript and Rollup: Rust Conquers (4)
- With Svelte, WebAssembly, TypeScript, and Rollup: Rust Conquers (5) ← You are here
In the previous article, we connected TypeScript, rollup.js, and WebAssembly.
Next, let's connect it with a frontend framework.
While we could have used Yew for the frontend, Rust—which requires a bit of extra effort just to get running—doesn't pair well with the frontend, which also requires meticulous adjustments.
Therefore, I chose a JavaScript framework.
However, I'm already tired of Vue and React, so I'll use Svelte, which has been a hot topic recently.
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
It is essentially Vue with the concept of Virtual DOM removed.
It is said that the amount of code is smaller compared to the other two.
Since writing everything from scratch would make this article too long, I will use a template this time.
ヾ(・ω<)ノ" 三三三● ⅱⅲ Roll, roll♪
------------------- ↓ The main topic starts here ↓-------------------
Prerequisites
This assumes that Rust and Node.js are up and running.
Please refer to the previous articles.
You are good to go if you can execute the following commands.
cargo --version
npm --verion
rustup target add wasm32-unknown-unknown
cargo install cargo-edit
Creating a project from the Svelte template
I will use a template that runs Svelte builds using rollup.js.
By default, it is configured for JavaScript, but there is a script provided to replace it with TypeScript.
Since the versions of the packages used are also old, I will reconfigure them to newer ones.
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

(・∀・) Easy, right!!
Adjusting rollup.js configuration
Before building WebAssembly, I will adjust the rollup.js configuration.
Add the wasm loader installed via npm to the configuration.
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(),
Preparing the WebAssembly module
Set up the Rust source code using the cargo command.
cargo init --lib
printf '[lib]\ncrate-type = ["cdylib", "rlib"]' | tee -a ./Cargo.toml
cargo add wasm-bindgen js-sys
Implementation
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn sum_numbers(numbers: &[i32]) -> i32 {
numbers.iter().sum()
}
Build
wasm-pack build --target web --release --out-name svelte-wasm
Implementing WebAssembly on the Svelte side
Source Code
Since WebAssembly basically needs to be called via asynchronous processing, I will change everything to be asynchronous.
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;
View side
<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>
Execution
npm run dev

(・∀・)(・∀・)Yeah!!!!
The frontend configuration is now finalized.
------------------- ↓ Postscript starts here ↓-------------------
Why didn't you use esbuild?
Chronologically, this article came first, but I have already published the following article.
Since things get complicated when there are too many elements, I have omitted the description regarding esbuild in this article.
Discussion