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.