Search code examples
javascriptwebassemblywasm-bindgen

How do I build a WebAssembly package that supports multiple bundlers?


I want to build a hybrid library (i.e. NPM package) using JavaScript (TypeScript) + WebAssembly (Rust). And I want to support multiple bundlers, not just Webpack. This seems difficult, since each bundler uses a slightly different approach for importing WASM:

// Webpack (experiments.asyncWebAssembly)
import { hello } from './my-lib.wasm'
hello()

// Rollup (using @rollup/plugin-wasm)
import init from './my-lib.wasm'
init().then(({ instance }) => { instance.exports.hello() })

// Parcel
import { hello } from './my-lib.wasm'
hello()
// ...or, if you want a promise
import('./my-lib.wasm').then(exports => { exports.hello() })

// Vite (note: this will be removed in v3.0,
// see https://github.com/vitejs/vite/discussions/7763)
import init from './my-lib.wasm'
init().then(exports => { exports.hello() })
// alternatively, use vite-plugin-wasm, which is the preferred approach for v3+
import { hello } from './my-lib.wasm'
hello()

I can't rely on JS bindings generated by wasm-bindgen, since AFAIK it is only compatible with Webpack.

// JS bindings generated by wasm-bindgen
import * as wasm from './my-lib_bg.wasm'
export function hello() { wasm.hello() }

Web apps don’t have this problem because they can choose their own bundler--but I don't know what bundler will process my code in advance.

How can I write a package that supports multiple bundlers? Can I somehow generate different entry points for each bundler?


Solution

  • I think the bundler target is the answer for the future, i.e. with WASM ESM integration. It's currently supported by Webpack and Vite (with my plugin you mentioned). In the future there'll be native support in browser and Node.js. But currently plugins may be needed to be created to support them in other bundlers.

    Another option for now is to use the web target, which requires your package's user to obtain the WASM file's URL from the bundler and initialize your plugin with it.