/esbuild-plugin-wasm

WASM module loader for esbuild

Primary LanguageTypeScriptMIT LicenseMIT

esbuild-plugin-wasm

An asynchronous .wasm file loader for esbuild. This allows you to directly import .wasm files as if they were a javascript module, similar to how it works in Webpack.

This plugin follows the WebAssembly/ES Module Integration proposal for loading WebAssembly from a JavaScript import statement.

Requirements

  • esbuild >= 0.11.0
  • node >= 10.0.0

⚠️ Important Note ⚠️

This loader makes use of top-level await, which only has partial support in esbuild. For now, it is only supported with the esm output format, not the iife or cjs formats. See evanw/esbuild#253

Installation

npm install --save-dev esbuild-plugin-wasm

or

yarn add --dev esbuild-plugin-wasm

Usage

  1. Add it to your esbuild plugins list

    CommonJS
    // build.js
    const esbuild = require('esbuild')
    const { wasmLoader } = require('esbuild-plugin-wasm')
    
    esbuild.build({
    ...
    plugins: [
        wasmLoader()
    ]
    ...
    });
    ESM
    // build.js
    import esbuild from 'esbuild'
    import { wasmLoader } from 'esbuild-plugin-wasm'
    
    esbuild.build({
    ...
    plugins: [
        wasmLoader()
    ]
    ...
    });
    Typescript
    // build.ts
    import esbuild from 'esbuild'
    import { wasmLoader } from 'esbuild-plugin-wasm'
    
    esbuild.build({
    ...
    plugins: [
        wasmLoader()
    ]
    ...
    });
  2. Then import and use your wasm in your project

    ESM
    // app.js
    import wasm from "./lib.wasm";
    
    console(wasm.add(1, 2));
    Typescript
    // app.ts
    import wasm from "./lib.wasm";
    
    console(wasm.add(1, 2));

Configuration

wasmLoader({
    // (Default) Deferred mode copies the WASM binary to the output directory,
    // and then `fetch()`s it at runtime. This is the default mode.
    mode: 'deferred'

    // Embedded mode embeds the WASM binary in the javascript bundle as a
    // base64 string. Note this will greatly bloat the resulting bundle
    // (the binary will take up about 30% more space this way)
    mode: 'embedded'
})