From a lot of Rust and WASM

WASM-PACK is optional.

WASM-Pack does a few things: 1) It compiles your code using wasm32-unknown-unknown, 2) It runs the wasm-bindgen cli (matching whatever version of wasm-bindgen you’re using) to generate JS glue 3) Lastly, it runs wasm-opt on the final webassembly

WASM-Bindgen is pretty powerful.

WASM-Bindgen can handle pretty sophisticated interfaces. I mostly end up just passing Uint8Arrrays into and out of the wasm module because my projects consist mostly of crypto keys, strings, and images. Frankly, if I could return multiple values than I wouldn’t need a single interface type but since I can’t return tuples to / from JS, I did end up using a simple type to represent a js keypair with public and private key fields. Using js-sys I can dynamically cast to that type from a generic JsValue. The cast performs an instanceof check so if you’re not using classes than make sure your object works with instanceof. Because wasm-bindgen is pretty efficient with the whole in / out of wasm memory stuff I’ve fully switched to letting it manage the interfaces and no longer use pointers manually to pull in and our of the wasm instance’s memory.

For target web, changing js that is imported by module requires a recompile

Not a big deal, but it’s bitten me a few times. wasm-bindgen copies the code from the es6 modules that you import into the target directory when using the web target (I don’t use bundlers during development so if you do then you might not encounter this problem). This makes the paths easier but does mean that if you change the modules that you import from you’ll need to re-run wasm-bindgen.

no-modules is required for service-workers

I can’t wait to stop using importScripts but for now, service workers aren’t able to use es6 modules. This means running wasm-bindgen with the no-modules target. Since wasm-bindgen doesn’t do any js copying for no-modules, you don’t need to rerun wasm-bindgen when you change JavaScript that is imported into your Rust code. On the down side (as is always the case with importScripts) everything is in the global namespace and dependency management is up to you.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Evan Brass

Evan Brass

I write a lot of ECMAScript… enough to have plenty of mistakes to learn from.