Rust with WebAssembly
Written
— Updated
- Rust WASM umbrella site: https://rustwasm.github.io/
- The
js_syscrate exposes bindings to a bunch of built-in JS types. - Converting Types
wasm_bindgenhas aJsValuetype that represents an arbitrary JS object.Thewasm_bindgendocs on interacting with types are also very useful: https://rustwasm.github.io/docs/wasm-bindgen/reference/types.htm- The
wasm_bindgendocs on interacting with types are also very useful: https://rustwasm.github.io/docs/wasm-bindgen/reference/types.html - Serde
- Docs
serdecan be made to work withJsValueby enabling theserde-serializefeature ofwasm-bindgen.wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
- Then you can use
SerializeandDeserializetraits as normal JsValue::from_serde(data)will serialize a Rust type to aJsValue.val::into_serde()will deserialize a value from aJsValueinto a Rust type.- This does run into issues with things like a
Uint8Arrayinside 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 aJsValueserde_wasm_bindgen::from_value(&js_value)to convert from aJsValueto a Rust type
- Errors
- Javascript Errors can be used with the
js_sys::Errortype. - 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-bindgento make it easier to publish WASM blobs. - Docs: https://rustwasm.github.io/docs/wasm-pack/introduction.html
- Use
wasm-packinstead ofcargoto 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
twiggytool 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
--profilingoption.[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