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][console_log]):


# #![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]
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`
cargo build --target wasm32-unknown-unknown --release
cargo run --manifest-path ../../crates/cli/Cargo.toml \
  --bin wasm-bindgen -- \
  ../../target/wasm32-unknown-unknown/release/wasm2js.wasm --out-dir .

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

# Move our original wasm out of the way to avoid cofusing Webpack.
mv wasm2js_bg.wasm wasm2js_bg.bak.wasm

npm install
npm run serve

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!