The maintainer of this website has a Spotify Coding Playlist of their Lo-fi Hip Hop beats!
Before getting started, be sure to check out all of the languages available, by clicking the "languages" dropdown in the header.
For our first program, we will be doing a "Hello world" type of program in Rust and wasm-pack.
To keep things simple with Wasm's limitations mentioned in the introduction example, instead of displaying a string, we will add two numbers together and display the result. Though, it is good to keep in mind, in later examples, a lot of these limitations will be abstracted away by your WebAssembly Language of choice (In this case, Rust). It is also highly recommended you take a look at the wasm-pack QuickStart Guide, as it will be referenced a lot in this example.
So first, Let's get rust installed, which includes cargo. Then, using cargo, let's install wasm-pack, which we will need later:
cargo install wasm-pack
Next, let's create our rust crate in our current directory using cargo:
cargo init
Then, let's edit our new Cargo.toml
to implement wasm-pack as mentioned in their quickstart:
[package]
name = "hello-world"
version = "0.1.0"
authors = ["Your Name <your@name.com>"]
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
Lastly, let's take a quick peek inside at the src/
directory. Since we are building a library (lib) to be used by a larger application, we need to rename the src/main.rs
to src/lib.rs
. Go ahead and do that now before moving forward.
Now that we have our project and environment setup, let's go ahead and start the actual implementation.
Let's go ahead and replace src/lib.rs
with the required use
call as mentioned in the quickstart, as well as our add function:
// The wasm-pack uses wasm-bindgen to build and generate JavaScript binding file.
// Import the wasm-bindgen crate.
use wasm_bindgen::prelude::*;
// Our Add function
// wasm-pack requires "exported" functions
// to include #[wasm_bindgen]
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
return a + b;
}
Then, let's compile our crate using wasm-pack, into a wasm module. Then run the following command, taking note of the --target web. The wasm-pack tool has support for a lot of different output types, especially for bundlers like Webpack or Rollup. But, since we want an ES6 module in our case, we use the web
target below:
wasm-pack build --target web
This will output a pkg/
directory containing our wasm module, wrapped in a js object. Next, lets create an index.js
JavaScript file, and import the outputted ES6 module in our pkg/
directory. Then, we will call our exported add()
function:
NOTE: In this example, we are using the exported function from the wasm module directly to help highlight the WebAssembly API.
wasm-bindgen
generates JavaScript bindings code that can be imported as an ES6 import, and is the recommended way to work with your Rust Wasm modules. These JavaScript bindings are shown in the "Passing High Level Data Types withwasm-bindgen
" example.
// Import our outputted wasm ES6 module
// Which, export default's, an initialization function
import init from "./pkg/hello_world.js";
const runWasm = async () => {
// Instantiate our wasm module
const helloWorld = await init("./pkg/hello_world_bg.wasm");
// Call the Add function export from wasm, save the result
const addResult = helloWorld.add(24, 24);
// Set the result onto the body
document.body.textContent = `Hello World! addResult: ${addResult}`;
};
runWasm();
Lastly, lets load our ES6 Module, index.js
Javascript file in our index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World - Rust</title>
<script type="module" src="./index.js"></script>
</head>
<body></body>
</html>
And we should have a working Wasm Add (Hello World) program! Congrats!
You should have something similar to the demo (Source Code) below:
Next let's take a deeper look at WebAssembly Exports.