A rollup plugin that compile Rust code into WebAssembly modules
tl;dr — see examples
This is a rollup plugin that loads Rust code so it can be interop with Javascript base project. Currently, the Rust code will be compiled as:
console
rustup default 1.28.0
rustup target add wasm32-unknown-unknown
This module requires a minimum of Node v8.9.0, Rollup v0.64.0, and Rust in [nightly channel][].
To begin, you’ll need to install rollup-plugin-rust
:
npm install rollup-plugin-rust --save-dev
Then add the plugin to your rollup
config. For example:
rollup.config.js
import rust from "rollup-plugin-rust";
export default [
{
input: "src/main.js",
output: {
file: "dist.index.js",
format: "esm"
},
plugins: [rust()]
}
];
rust
#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
js
import wasm from "lib.rs";
export async function increment(a) {
const { instance } = await wasm;
return instance.exports.add(1, a);
}
And run rollup
via your preferred method.
export
export
in webassembly-loader. (see examples)js
// in your rollup.config.js
{
plugins: [rust({ export: "instance" })];
}
target
String
wasm32-unknown-unknown
js
// in your rollup.config.js
{
plugins: [rust({ target: "wasm32-unknown-emscripten" })];
}
release
Boolean
true
js
// in your rollup.config.js
{
plugins: [rust({ release: false })]; // preserve debug symbol
}
include
Array<string>
or string
['**/*.rs']
js
// in your rollup.config.js
{
plugins: [
rust({
include: ["src/**/*.rs", "test/**/*.rs"]
})
];
}
exclude
Array<string>
or string
['node_modules/**', 'target/**']
js
// in your rollup.config.js
{
plugins: [
rust({
exclude: ["**/node_modules/**", "**/target/**", "**/__caches__/**"]
})
];
}
See the test cases and example projects in fixtures and examples for more insight.
rust
#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
toml
[package]
name = "adder"
version = "0.1.0"
authors = ["Full Name <email@site.domain>"]
[lib]
crate-type = ["cdylib"]
path = "lib.rs"
{export: 'buffer'}
js
import wasmCode from "./lib.rs";
WebAssembly.compile(wasmCode).then(module => {
const instance = new WebAssembly.Instance(module);
console(instance.exports.add(1, 2)); // 3
});
{export: 'module'}
js
import wasmModule from "./lib.rs";
const instance = new WebAssembly.Instance(wasmModule);
console(instance.exports.add(1, 2)); // 3
{export: 'instance'}
js
import wasm from "./lib.rs";
console(wasm.exports.add(1, 2)); // 3
{export: 'async'}
rust
extern {
fn hook(c: i32);
}
#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
hook(a + b)
}
js
import wasmInstantiate from "./lib.rs";
wasmInstantiate(importObject | undefined).then(({ instance, module }) => {
console(instance.exports.add(1, 2)); // 3
// create different instance, extra will be called in different environment
const differentInstance = new WebAssembly.Instance(module, {
env: {
hook: result => result * 2
}
});
console(differentInstance.exports.add(1, 2)); // 6
});
{export: 'async-instance'}
js
import wasmInstantiate from "./lib.rs";
wasmInstantiate(importObject | undefined).then(instance => {
console(instance.exports.add(1, 2)); // 3
});
{export: 'async-module'}
js
import wasmInstantiate from "./lib.rs";
wasmCompile(importObject | undefined).then(module => {
const differentInstance = new WebAssembly.Instance(module);
console(differentInstance.exports.add(1, 2)); // 3
});