Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use with esbuild, I can't figure out how to use this with esbuild #222

Open
okikio opened this issue Dec 25, 2021 · 3 comments
Open

Comments

@okikio
Copy link

okikio commented Dec 25, 2021

I'm trying to use brotli-wasm on bundle.js.org, but I can't figure out how to compile it properly for esbuild, and I can't switch to webpack, I'm stuck, so, I thought I would ask here, do you have any advice that might help?

@dfrankland
Copy link
Owner

I've never used ESBuild. Do you have a reproduction of the issue? Or perhaps you can provide some logs?

@okikio
Copy link
Author

okikio commented Dec 27, 2021

After doing some more experiments, I've determined that the problem is due to the WASM import. The fetch location is already set in stone, not being able to change the fetch location for the WASM file is what is causing problems.

This is the error I'm getting,
image

Note: I've already checked through the esbuild-plugin-wasm, no matter how much tweaking I do to the plugin, I can't fix this error from the plugin side, so, I think it's best to try to fix it from this side.

For my project, I use a gulpfile, which builds my project, but because I place all js related files in a /js/ folder, when I try to use wasm-brotli it expects the WASM file to be located at ./wasm_background_bg.wasm, when I use it. It would be awesome, if you could instantiate the WASM file, using a similar syntax to esbuild-wasm (https://esbuild.github.io/api/#running-in-the-browser),
e.g.

import { initialize, compress } from 'wasm-brotli';

(async () => {
  await initialize({
    wasmURL: './js/wasm_background_bg.wasm',
  });

  let compressedData = await compress(new TextEncoder().encode("Hello There"));
  console.log(compressedData)
})()

I created a branch you can use for testing, https://github.com/okikio/bundle/tree/brotli-wasm, sorry for the late response.

@MRayermannMSFT
Copy link

MRayermannMSFT commented Nov 16, 2023

I'm also trying to use this package (indirectly, via https://github.com/LibertyDSNP/parquetjs) with esbuild, but in a node envrionment, and was able to get it to work.

Ultimately I simply I had to create a plugin to inline the .wasm binary in the esbuild bundle. I based my work off of this example: https://esbuild.github.io/plugins/#webassembly-plugin

I say "based my work off of" because the way this package loads its .wasm binary is not compatible with the example plugin. The example plugin assumes the .wasm binary is being loaded via import or require, however, this package loads the .wasm binary by reading the file contents and then initializing the WebAssembly module.

This is what I ended up with:

const wasmPlugin = {
    name: 'wasm',
    setup(build) {
        const path = require('path')
        const fs = require('fs')
        build.onResolve({ filter: /wasm_brotli_nodejs_bg/ }, args => {
            if (args.namespace === 'wasm-stub') {
                return {
                    path: args.path,
                    namespace: 'wasm-binary',
                }
            } else {
                const wasmBinaryAbsolutePath = path.resolve(path.dirname(args.importer), args.path + ".wasm");
                if (fs.existsSync(wasmBinaryAbsolutePath)) {
                    return {
                        path: wasmBinaryAbsolutePath,
                        namespace: 'wasm-stub',
                    }
                }
            }
        })
        build.onLoad({ filter: /.*/, namespace: 'wasm-stub' }, async (args) => ({
            contents: `import wasm from ${JSON.stringify(args.path)}
              export default (imports) =>
                WebAssembly.instantiate(wasm, imports).then(
                  result => result.instance.exports)`,
        }))
        build.onLoad({ filter: /.*/, namespace: 'wasm-binary' }, async (args) => ({
            contents: await fs.promises.readFile(args.path),
            loader: 'binary',
        }))
    }
}

Hopefully this helps future lost souls. 🫡

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants