#rust #webassembly #javascript
wasm-bindgen is an awesome tool made by rustwasm team, make it very easy to expose Rust's data/functions to JavaScript and vice versa.
To use, you can add a #[wasm_bindgen]
as an annotation the code where you want to be exposed or import to/from JavaScript, for example:
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
With the above code, we import the alert()
function from JavaScript to Rust, and expose Rust's greet()
function to JavaScript.
A Rust struct will be exposed as a class in JavaScript:
#[wasm_bindgen]
pub struct Foo {
contents: u32,
}
#[wasm_bindgen]
impl Foo {
#[wasm_bindgen(constructor)]
pub fn new() -> Foo {
Foo { contents: 0 }
}
}
You can import an ES6 module to use in Rust:
#[wasm_bindgen(module = "./bar")]
extern "C" {
fn blah(bleh: &JsValue);
}
// blah() function is in bar.js
There are two attributes you need to know about, js_namespace
: indicates the JavaScript type for your binding, and js_name
for the function name. We can use them to import multiple signatures of a polymorphic JavaScript function, like this:
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console, js_name = log)]
fn log_str(s: &str);
#[wasm_bindgen(js_namespace = console, js_name = log)]
fn log_u32(n: u32);
}
Using js_name
, you can rename not just function, but also classes or types, for example:
#[wasm_bindgen]
extern "C" {
// Import JavaScript's String type as JsString in Rust
#[wasm_bindgen(js_name = String)]
type JsString;
}
And if you're renaming type names, you need to use js_class
attribute when binding a function of that type:
#[wasm_bindgen(method, js_class = "String", js_name = charAt)]
fn char_at(this: &JsString, index: u32) -> JsString;
The web_sys
crate also provides some good binding from JS:
use web_sys::console;
console::log_1(&"Hello using web-sys".into());
Finnaly, use wasm-pack to build your Rust project into a WebAssembly module, then use it in your JavaScript project.
wasm-pack build
If you're using TypeScript or NodeJS, you might want to take a look at wasm-bindgen command line tool https://rustwasm.github.io/wasm-bindgen/reference/cli.html
Bonus: If you're working with various data type/struct, it's very helpful to use serde for serializing/deserializing into and from JS. See more at https://rustwasm.github.io/wasm-bindgen/reference/arbitrary-data-with-serde.html
Compile Rust to WebAssembly
#rust #webassembly A Rust program can be compiled to WebAssembly as a library or a full runnable entry point (if the project type is binary…
Home Page
Welcome! Look like you've found my personal notebook. This is the place where you can take a peek into my mind to see what I've been…
If you think this note resonated, be it positive or negative, please feel free to send me an email and we can talk.