Rust with WebAssembly
Written
— Updated
- Rust WASM umbrella site: https://rustwasm.github.io/
- The
js_sys
crate exposes bindings to a bunch of built-in JS types. - Converting Types
wasm_bindgen
has aJsValue
type that represents an arbitrary JS object.Thewasm_bindgen
docs on interacting with types are also very useful: https://rustwasm.github.io/docs/wasm-bindgen/reference/types.htm- The
wasm_bindgen
docs on interacting with types are also very useful: https://rustwasm.github.io/docs/wasm-bindgen/reference/types.html - Serde
- Docs
serde
can be made to work withJsValue
by enabling theserde-serialize
feature ofwasm-bindgen
.wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
- Then you can use
Serialize
andDeserialize
traits as normal JsValue::from_serde(data)
will serialize a Rust type to aJsValue
.val::into_serde()
will deserialize a value from aJsValue
into a Rust type.- This does run into issues with things like a
Uint8Array
inside an object, because it just gets JSON stringified which doesn't work well.- The serde-wasm-bindgen crate works around this by doing a direct serialization instead of an intermediary JSON step.
serde_wasm_bindgen::to_value(&value)
to convert from a Rust type to aJsValue
serde_wasm_bindgen::from_value(&js_value)
to convert from aJsValue
to a Rust type
- Errors
- Javascript Errors can be used with the
js_sys::Error
type. - You can wrap any error into a JS Error like this
- Javascript Errors can be used with the
- wasm-pack
- This is a tool that works with
wasm-bindgen
to make it easier to publish WASM blobs. - Docs: https://rustwasm.github.io/docs/wasm-pack/introduction.html
- Use
wasm-pack
instead ofcargo
to build your application. - Commands
wasm-pack new <PROJECT>
- Create a new WASM project with Cargo.toml already set up and a skeleton source file.wasm-pack build
- Build the library. This will also install the necessary toolchain if you don't have the WASM target installed yet.
- This is a tool that works with
- Examining output size
- Since WASM is often consumed in the browser, output size can be a concern. The
twiggy
tool can be used to show what is taking up space. - It does need the names section present though, and so adding this to your Cargo.toml will prevent wasm-pack from stripping the names when passing the
--profiling
option.[package.metadata.wasm-pack.profile.profiling] # previously had just ['-O4'] wasm-opt = ['-O4', '-g']
- Since WASM is often consumed in the browser, output size can be a concern. The