Git Product home page Git Product logo

rollup-plugin-wasm-bindgen-web's Introduction

rollup-plugin-wasm-bindgen-web

CI Coverage Status Language grade: JavaScript

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.


Table of Contents

What is this

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.

Installation

Add the registry to .npmrc:

@alorel:registry=https://npm.pkg.github.com

Then install it:

npm install @alorel/rollup-plugin-wasm-bindgen-web

Requirements & basic setup

  • 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.

The transformation

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)
  ));

The plugin config

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;
}

Filtering

There are two sets of files to match. Using the my_lib example from earlier,

  • wasmFilter should match my_lib.js
  • jsFilter should match files that'll contain the dynamic import()s

Raw wasm output

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;
"#;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.