[WASM] Set up wasm-bindgen for easy Rust/JavaScript Interoperability
Interoperability between JavaScript and Rust is limited to numerics and accessing memory directly. Since this can be exhausting and overwhelming to do manually the Rust/Wasm team has created the wasm-bindgen project to facilitate high-level interactions between Rust and JavaScript.
WebAssembly programs operate on a limited set of value types. Due to this, the functions bridging between JavaScript and Rust only allow for primitive numeric types, like integer or float.
So if you pass a string between Javascript and WASM, it convert to a number.
This is not what we wanted to achieve here. Fortunately, we can work around this by directly reading or writing to WebAssembly's memory using JavaScript. Each WASM module has a linear memory, which is initialized during instantiation.
While sometimes accessing memory directly can be useful, in most cases, it's quite cumbersome. That's why the generic bindgen-style framework, wasm-bindgen, was created. The framework makes it possible to write idiomatic Rust function signatures that map to idiomatic JavaScript functions automatically.
To get started, we add wasm-bindgen
as a dependency to our Cargo configuration.
# Cargo.toml [package] name = "utils" version = "0.1.0" authors = ["zhentian-wan <answer881215@gmail.com>"] edition = "2018" [dependencies] wasm-bindgen="0.2" [lib] crate-type = ["cdylib"]
lib.rs:
#![feature(use_extern_macros)] extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen(module = "../domUtils")] extern { fn appendStringToBody(s: &str); } #[wasm_bindgen] pub extern fn run() { appendStringToBody("Hello World"); }
We compile our Rust library using wasm-pack build
wasm-pack build
This way, we can pass types, like strings, into our Rust code without manually having to take care of the conversion.
domUtils.js:
export const appendStringtoBody = (value) => { const text = document.createTextNode(value); document.body.appendChild(text); }
When using wasm-bindgen
, we then can declare that the module
should be imported.
Run:
wasm-pack build
npx webpack-dev-server