yew helps you making a frontend application.
I remind how to do it.
Prerequests
I need some tools to do it.
Basically it is clear what I need by reading yew official document.
Now I choose wasm-pack
to build a wasm application.
$ cargo install wasm-pack
$ cargo new myapp
$ cd myapp
So, I need edit Cargo.toml
to build using wasm-pack
.
[dependencies]
yew = { version = "0.14.3", features = ["web_sys"] }
wasm-bindgen = "0.2"
[lib]
crate-type = ["cdylib"]
Done.
Write Rust code
I defined my rust application as lib
type although I created my project as bin
type.
So I modified my project looks like now.
myapp
- src
- app.rs # my application body (renamed from `main.rs`)
- lib.rs # entrypoint of wasm application (added by manually)
- Cargo.toml
- Cargo.lock
app.rs
looks like below.
use yew::prelude::*;
pub struct Model {
link: ComponentLink<Self>,
value: i64,
}
pub enum Msg {
AddOne,
SubOne,
}
impl Component for Model {
type Message = Msg;
type Properties = ();
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
Self {
link,
value: 0,
}
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::AddOne => self.value += 1,
Msg::SubOne => self.value -= 1,
}
true
}
fn view(&self) -> Html {
html! {
<div>
<button onclick=self.link.callback(|_| Msg::AddOne)>{ "+1" }</button>
<button onclick=self.link.callback(|_| Msg::SubOne)>{ "-1" }</button>
<p>{ self.value }</p>
</div>
}
}
}
And lib.rs
is
use yew;
use wasm_bindgen::prelude::*;
mod app;
#[wasm_bindgen]
pub fn start() {
yew::initialize();
yew::App::<app::Model>::new().mount_to_body();
}
wasm_bindgen
allows to us using our Rust code in javascript world, awesome.
Build Rust code to wasm application
After wrote Rust code with yew
, I must run wasm-pack
for building it.
$ wasm-pack build
So, wasm-pack
without any parameter generates pkg
directory.
pkg
directory has many stuffs that I don't know there are, but I know that there work fine :-).
Write my frontend code
Now I have wasm code generated by Rust code.
All I need is using it, HOW?
You know anytime MDN documents helps us, refer this article.
$ mkdir site
$ cd site
$ npm init
$ npm i -D webpack webpack-dev-server webpack-cli
$ npm i ../pkg
OK, next I write webpack.config.js
const path = require('path');
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
},
mode: 'development',
devServer: {
host: '0.0.0.0',
port: 55301,
},
};
And index.html
and inde.js
which calls the wasm application.
index.js
is
const js = import('./node_modules/myapp/myapp.js');
js.then(js => js.start());
index.html
is
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>anond browser</title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
Run server
Now I can ensure my application works fine.
$ npx webpack-dev-server
Looks good.
HOT RELOAD?
Yes, of course.
I modify my Rust code while running dev server.
...
html! {
<div>
<h1>{ "Modifying" }</h1>
...
</div>
}
...
Build manually.
$ wasm-pack build
After building, dev server detected this changing and reloaded the built wasm application. It means my browser was refreshed and shows new sentence added by me.
I just said AWESOME EASY, yeah.
Top comments (2)
If you need server rendering today, I recommend looking at github.com/chinedufn/percy,
and if you don't, github.com/Pauan/rust-dominator.
The latter beats Svelte performance and memory usage, by using the right concepts like github.com/ryansolid/solid does for JS. You might even want to explore using the underlying github.com/Pauan/rust-signals for non-frontend purposes.
I appriciate your comment!
They are the ones I hardly knew. I gonna play with them.