WebAssembly is a compilation target for "lower level" languages like: C/C++/Rust (and others). This means that we can compile non-JS programs and run them in the browser.
Because of JavaScript's dynamic nature you cannot bypass all the optimization process done by the engine. Even though JavaScritp is pretty fast we can still have things even ⚡ faster ⚡.
(Images above courtesy of Lin Clark)
The WebAssembly
namespace
- Module: The compiled wasm representation.
- Instance: The actual module with all the functions exported.
- Memory
The first shared layer between our JavaScript environment and our WASM module is the memory. WebAssembly manages state threw a linear memory represented by an
ArrayBuffer
.ArrayBuffer
's on their own are an intermediate representation of a blob of raw byte data. To work with this blob we will need a way shape it to our needs. Entering:TypedArrays
.
const rawBuff = new ArrayBuffer(16);
const view8 = new Uint8Array(rawBuff);
const view32 = new Uint32Array(rawBuff);
view32[0] = 1;
view32[1] = 2;
4: Data types:
- i32: 32-bit integer
- i64: 64-bit integer
- f32: 32-bit floating point
- f64: 64-bit floating point
Disclaimer: pros/cons from a newbie's point of view. Highly experienced proffesionals may have a different perspective
pros:
- battle tested
cons:
- steep learning curve
- overwhelming docs
- setting up everything can be awkward
- low level js glue code
pros:
- no extra tooling, just the Rust compiler
wasm-bindgen
a more high level approach of JS ⇔ wasm interaction- easy setup
- more "smarter" js glue code
cons:
- bleeding edge-ish, still under development (need Rust beta)
- rustup Similar to npm's NVM, it is a way to simply switch between Rust versions
- cargo Similar to npm, cargo is the official package manager for Rust
- rustc Rust's compiler
Everything is immutable by default.
- ownership
fn main() {
let vec = vec![1, 2, 3];
let vec1 = vec;
println!("{:?}", vec);
}
- borrowing
fn print_vec(vec: &Vec<i32>) {
println!("{:?}", vec);
}
fn main() {
let vec = vec![1, 2, 3, 4];
print_vec(&vec);
print_vec(&vec);
}
To run the examples above, simply copy paste them into a .rs
file and then follow these steps:
$ rustc example.rs
# By default it should output an executable file with the same name as the source file
$ ./example
Our arsenal for tackling WebAssembly (docs)
wasm-pack
The superhero in our movie. This tool manages our workflow and helps us create, build and ship WebAssembly codecargo-generate
This tool will generate us a Rust boilerplate project just to get us started fast.wasm-bindgen
Our second superhero in our movie. This bad boy will be our main tour guide from Rust world to JS world and back.create-wasm-app
An npm init project for generating a project that consumes rust-generated wasm via webpacknpm
Needs no introwebpack 4
Also needs no introduction
Two official patterns for dealing with complex structures:
Preparing the Rust repo
$ git clone [email protected]:andrei-cacio/wasm-fuzzy-search.git
$ cd wasm-fuzzy-search
$ wasm-pack build
Preparing the JS app
$ git clone [email protected]:andrei-cacio/fuzzy-search-app.git
$ cd fuzzy-search-app
$ npm i
$ npm link ../wasm-fuzzy-search
$ npm start