-
-
Notifications
You must be signed in to change notification settings - Fork 58
quickstart
Our first example is a counter that can be incremented or decremented. The complete code is found here
I assume you already installed rust and cargo binaries already. If not, then you can install by issuing the following command from your terminal.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
To create a rust project with sub code in it. Issue the command:
cargo new --lib counter
This will create a library crate with counter
as the package name.
Edit the Cargo.toml
file to set the library crate-type to cdylib
[^0].
[package]
name = "counter"
version = "0.1.0"
authors = ["Your name <[email protected]>"]
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
sauron = "0.32"
We also need to add sauron
as a dependecy of the project.
Add this code to src/lib.rs
src/lib.rs
use sauron::html::text;
use sauron::prelude::*;
use sauron::{node, Cmd, Component, Node, Program};
#[derive(Debug)]
pub enum Msg {
Increment,
Decrement,
}
pub struct App {
count: i32,
}
impl App {
pub fn new() -> Self {
App { count: 0 }
}
}
impl Component<Msg> for App {
fn view(&self) -> Node<Msg> {
node! {
<main>
<input type="button"
value="+"
key="inc"
on_click=|_| {
Msg::Increment
}
/>
<div>{text(self.count)}</div>
<input type="button"
value="-"
key="dec"
on_click=|_| {
Msg::Decrement
}
/>
</main>
}
}
fn update(&mut self, msg: Msg) -> Cmd<Self, Msg> {
match msg {
Msg::Increment => self.count += 1,
Msg::Decrement => self.count -= 1,
}
Cmd::none()
}
}
#[wasm_bindgen(start)]
pub fn main() {
Program::mount_to_body(App::new());
}
And finally our index.html
file
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
<title>Counter</title>
</head>
<body>
<script type=module>
import init from './pkg/counter.js';
init().catch(console.error);
</script>
</body>
</html>
This is the minimal set of files in order to compile and run our project as a web application.
Next, we need to install wasm-pack
, to simplify our workflow of our project to compile to webassembly.
cargo install wasm-pack
Invoking the command:
wasm-pack build --release --target=web
wasm-pack
adds arguments to the rust compiler to compile our code into webassembly and link it to a javascript module.
All of this is abstracted with wasm-pack
, so we don't have to think about it.
We only care about our js file ./pkg/counter.js
that is generated in pkg
directory in our project folder.
Next, we need to statically serve the index.html
such that the browser can run the .wasm
[^wasm] binary in the browser
[^0]: use cdylib
for crate-type if you want to build it as wasm entry point crate.
If you also want this crate as a reusable component from your other crate, then you can add rlib
as crate-type.
[lib]
crate-type = ["cdylib", "rlib"]
[^wasm]: wasm
files can not be executed in the browser unless serve from the same domain as the index.html
which reference it.