Converting WebAssembly to JS

View full source code

Not all browsers have support for WebAssembly at this time (although all major ones do). If you'd like to support older browsers, you probably want a method that doesn't involve keeping two codebases in sync!

Thankfully there's a tool from binaryen called wasm2js to convert a wasm file to JS. This JS file, if successfully produced, is equivalent to the wasm file (albeit a little bit larger and slower), and can be loaded into practically any browser.

This example is relatively simple (cribbing from the console.log example):


# #![allow(unused_variables)]
#fn main() {
use wasm_bindgen::prelude::*;

// lifted from the `console_log` example
#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[wasm_bindgen(start)]
pub fn run() {
    log("Hello, World!");
}

#}

The real magic happens when you actually build the app. Just after wasm-bindgen we see here how we execute wasm2js in our build script:

#!/bin/sh

set -ex

# Compile our wasm module and run `wasm-bindgen`
wasm-pack build

# Run the `wasm2js` tool from `binaryen`
wasm2js pkg/wasm2js_bg.wasm -o pkg/wasm2js_bg.wasm.js

# Update our JS shim to require the JS file instead
sed -i 's/wasm2js_bg.wasm/wasm2js_bg.wasm.js/' pkg/wasm2js.js
sed -i 's/wasm2js_bg.wasm/wasm2js_bg.wasm.js/' pkg/wasm2js_bg.js

Note that the wasm2js tool is still pretty early days so there's likely to be a number of bugs to run into or work around. If any are encountered though please feel free to report them upstream!

Also note that eventually this will ideally be automatically done by your bundler and no action would be needed from you to work in older browsers via wasm2js!