DEV Community

mtwtkman
mtwtkman

Posted on • Edited on

Write a frontend application with Rust

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
Enter fullscreen mode Exit fullscreen mode

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"]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

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();
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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,
  },
};
Enter fullscreen mode Exit fullscreen mode

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());
Enter fullscreen mode Exit fullscreen mode

index.html is

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>anond browser</title>
    </head>
    <body>
        <script src="./index.js"></script>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Run server

Now I can ensure my application works fine.

$ npx webpack-dev-server
Enter fullscreen mode Exit fullscreen mode

Alt Text

Looks good.

HOT RELOAD?

Yes, of course.
I modify my Rust code while running dev server.

...
html! {
    <div>
        <h1>{ "Modifying" }</h1>
        ...
    </div>
}
...
Enter fullscreen mode Exit fullscreen mode

Build manually.

$ wasm-pack build
Enter fullscreen mode Exit fullscreen mode

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.

Alt Text

I just said AWESOME EASY, yeah.

Top comments (2)

Collapse
 
qm3ster profile image
Mihail Malo

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.

Collapse
 
mtwtkman profile image
mtwtkman

I appriciate your comment!
They are the ones I hardly knew. I gonna play with them.