Esbuild: wasm filetype loader

Created on 22 Sep 2020  路  3Comments  路  Source: evanw/esbuild

Adding a quick request to support .wasm filetypes being bundled, similar to how webpack works. The specific use case:

  1. Compile a package using wasm-bindgen or wasm-pack with --target bundler
  2. Use this package within an esbuild project.

The alternative right now is to use wasm-bindgen with a target of web and load the wasm file via fetch.

Most helpful comment

It seems to me like it would be best to experiment with doing this as a plugin, which will be possible once the plugin API is released. The plugin API is currently a work in progress, and is being tracked as issue #111.

All 3 comments

It seems to me like it would be best to experiment with doing this as a plugin, which will be possible once the plugin API is released. The plugin API is currently a work in progress, and is being tracked as issue #111.

I just tried this out and it seems pretty straightforward. Here's an example plugin:

let path = require('path')
let util = require('util')
let fs = require('fs')

let wasmPlugin = plugin => {
  plugin.setName('wasm-loader')

  plugin.addResolver({ filter: /\.wasm$/ }, args => ({
    path: path.isAbsolute(args.path) ? args.path : path.join(path.dirname(args.importer), args.path),
    namespace: args.namespace === 'wasm-stub' ? 'wasm-binary' : 'wasm-stub',
  }))

  plugin.addLoader({ filter: /.*/, namespace: 'wasm-binary' }, async (args) =>
    ({ contents: await util.promisify(fs.readFile)(args.path), loader: 'binary' }))

  plugin.addLoader({ filter: /.*/, namespace: 'wasm-stub' }, async (args) => ({
    contents: `import wasm from ${JSON.stringify(args.path)}
      export default async (imports) =>
        (await WebAssembly.instantiate(wasm, imports)).instance.exports` }))
}

If you generate WebAssembly using wasm-pack with this Rust code:

#[wasm_bindgen]
pub fn add(x: i32, y: i32) -> i32 {
  x + y
}

You can use it like this:

import load from './example.wasm'
load().then(({ add }) => {
  console.log(add(1, 2))
})

Obviously real-world code would be somewhat more complicated but the current plugin API seems sufficient to enable this functionality.

Plugin documentation has been released: https://esbuild.github.io/plugins/. You should be able to do this yourself now. There is even an example WebAssembly plugin as a starting point: https://esbuild.github.io/plugins/#webassembly-plugin.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Gotterbild picture Gotterbild  路  3Comments

aelbore picture aelbore  路  3Comments

mohsen1 picture mohsen1  路  3Comments

wcastand picture wcastand  路  4Comments

mixtur picture mixtur  路  4Comments