When jco
transpiles a WebAssembly Interface Types (WIT) component for wasm32-wasi
target, it generates a number of .js
and .wasm
files if you use the wasi
shims (like clocks
, random
, etc.). These files need to be bundled together to be used in the browser. Notably, the .wasm
file needs to be converted to a Blob URL and the .js
files need to be bundled together. This package includes a plugin which finds the .wasm
files and transforms them into Blob URLs so they can be resolved by fetching that URL in the bundled .js
file.
Thus, this plugin allows you to take WebAssembly component bytes and import it into the browser.
In the end, you get an ES Module with your Wasm functions exported.
See the example for the latest usage.
There is a convenience function call load
that is exported from this library which makes combining .wasm
bytes and importables
easy. All you need are your wasm bytes and your importable functions.
Demo usage is at src/routes/+page.svelte.
To bundle your wit-component for the browser:
// You need to give the JavaScript code to `jco` so it can wire it up to the wasm component
let importableCode = `export function prnt(string) {
console.log('from imported code: ', string);
};`
// Make sure you're in the Browser environment when importing the plugin
// The Vite bundler bundles this library for the Browser environment
const { load } = await import('rollup-plugin-wit-component');
// Load the wasm component bytes as an array buffer
let wasmBytes = await fetch(wasmURL).then((res) => res.arrayBuffer());
// Map the WIT interface name to the code that implements the interface
let importables = [{ 'component:cargo-comp/imports': importableCode }];
// Load the wasm component + imports to get the exported module functions
let mod = await load(wasmBytes, importables);
// mod.an_export_function() is now available and can call prnt function.
-
First you need a Wasm Interface Type Component to load. A demo component written in Rust is located at
crates/demo
. -
The component from 1) needs to implement the interface, which is defined in the wit file
crates/demo/wit/world.wit
.
More details located in README.md
.
Ensure you have cargo-component
installed:
cargo install cargo-component
You can bundle, build, and run preview all with a single just command from the justfile:
just preview
Build the demo crate with
cargo component build --package demo --release
This will generate the wasm bytes at target/wasm32-wasi/release/demo.wasm
.
Once you've created a project and installed dependencies with npm install
(or pnpm install
or yarn
), start a development server:
npm run build
# start the server and open the app in a new browser tab
npm run preview
Note that due to the way Vite handles dynamic wasm, we cannot (yet?) use npm run dev
to start the server.
Up rev the version in package.json
and then run:
# up revs the version in package-lock.json
npm install
# builds the dist folder
npm run package
# publishes to npm
npm publish