Note: semantic-release
starts at v1, but this plugin is in early alpha and should be considered unstable and prone
to breaking changes, although any such changes will follow semantic versioning.
This is a rollup plugin for importing wasm files generated by wasm-bindgen; it's an early proof of concept and may or may not handle all scenarios.
Add the registry to .npmrc
:
@alorel:registry=https://npm.pkg.github.com
Then install it:
npm install @alorel/rollup-plugin-wasm-bindgen-web
- wasm-bindgen must output in
web
mode - the resulting js file must be imported via dynamic import, i.e.
import('./foo')
Given a Rust input like this:
use wasm_bindgen::prelude::*;
#[wasm_bindgen(js_name = multiplyByTwo)]
pub fn multiply_by_two(num: i32) -> i32 {
num * 2
}
And a build command sequence like this:
cargo build --release --target wasm32-unknown-unknown;
wasm-bindgen target/wasm32-unknown-unknown/release/my_lib.wasm --out-name my_lib --target web;
You'd produce four files: my_lib.js
, my_lib.d.ts
, my_lib_bg.wasm
, my_lib_bg.wasm.d.ts
The file you want to be import()
ing is my_lib.js
; it contains an asynchronous initialiser function that the plugin
will call and await on before giving you the import's response.
Whenever the plugin sees that you're importing the js file of your wasm-bindgen output, it'll emit the associated wasm file as an asset and reformat your import:
import('./wasm/my_lib')
.then(lib => console.log(lib.multiplyByTwo(2), "That'll be 4"));
will get transformed into
import __wasmBindgenRollupPluginDynamicImportLoader from '@alorel/rollup-plugin-wasm-bindgen-web/autoinit-wasm-import';
__wasmBindgenRollupPluginDynamicImportLoader(import('./wasm/my_lib'), 'urlOfWasmFile.wasm')
.then(lib => {/* ... */
});
Where the loader returns the following:
Promise
.all([dynamicImport, fetch(url)])
.then(([wasmModule, response]) => (
wasmModule.default(response)
.then(() => wasmModule)
));
import {wasmBindgen} from '@alorel/rollup-plugin-wasm-bindgen-web';
export default {
// ... your config
plugins: [
wasmBindgen(config)
]
}
Where config
is the following interface:
/** Standard Rollup filter */
interface Filter {
exclude?: FilterPattern;
include?: FilterPattern;
}
interface Opts {
/**
* When set to true, adds a __getWasm() function to the import() response which returns what the original
* init function returned
* @default false
*/
exposeWasm?: boolean;
/**
* JS source files to look for dynamic imports in.
* @default {include: /\.[jt]sx?$/}
*/
jsFilter?: Filter;
/**
* Whether to include a source map in the generated code
* @default true
*/
sourceMap?: boolean;
/**
* Filter to match dynamically imported wasm-bindgen output files
* @default Don't match anything
*/
wasmFilter?: Filter;
}
There are two sets of files to match. Using the my_lib
example from earlier,
wasmFilter
should matchmy_lib.js
jsFilter
should match files that'll contain the dynamicimport()
s
By default, the response of the original init function is hidden. You can turn the exposeWasm
option on to append
a __getWasm
function to the module which will return it. If you're using Typescript, you can correct your typings by
adding the following to your Rust source files (constant name doesn't matter):
#[wasm_bindgen(typescript_custom_section)]
const TS_APPEND_CONTENT: &'static str = r#"
export function __getWasm(): InitOutput;
"#;