Can’t find a way to disable WebAssembly parser

Bug report

What is the current behavior?

WebAssembly parser kicks in even when module.noParse is set to /.wasm$/

If the current behavior is a bug, please provide the steps to reproduce.

Please see this conversation for a deeper context – NeekSandhu/onigasm#2 (comment)

mkdir wasm-test
cd wasm-test
npm init -y
npm i onigasm
npm i -D webpack webpack-cli
// index.js
import {
    loadWASM
} from 'onigasm'

(async () => {
    // see https://www.npmjs.com/package/onigasm#light-it-up
    await loadWASM(require('file-loader!onigasm/lib/onigasm.wasm'))
})()
// webpack.config.js

module.exports = {
    mode: 'development',
    entry: __dirname + '/index.js',
    output: {
        filename: 'bundle.js'
    },
    module: {
        noParse: /onigasm.wasm/,
        rules: [{
            test: /\.wasm$/,
            use: "file-loader"
        }]
    }
};

After the setup above is compiled, and grep is done on bundle.js for [fileLoaderHash].wasm no result will be found because allegedly, WebAssembly parser interupted the process.

What is the expected behavior?
Call to loadWASM should get populated with valid URL to ongiasm.wasm file. Courtesy of file-loader.

Other relevant information:
webpack version: 4.8.1
Node.js version: 8.9.1
Operating System: Windows 10 64bit
Additional tools: NA

Author: Fantashit

4 thoughts on “Can’t find a way to disable WebAssembly parser

  1. Totally agree.

    Would be certainly cool, but AFAIK the main challenge here that emscripten takes a bunch of compiler flags when compiling and those flags get baked into the glue code. Those flags go hand-in-hand with .wasm file and respective .js file. The challenge?? How do we go about doing that process without involving emscripten?

    Well, the flags that actually get baked into .js glue are things like memory size, whether or not dynamic memory size increase is allowed, should host kill the WASM runtime, etc. At the moment, these things are passed to the emcc command on the CLI and there is no way for us (webpack) to know what those args were so we can synthesize the glue code ourselves. Uncool.

    But maybe we can brew a new way of declaring those “things”. Why not declare those things in a file, lets say [lib_name].wasm.config or [lib_name].wasm.json that lives in the same directory as the [lib_name].wasm itself.

    Example:

    {
      "EXPORT_NAME": "Onigasm",
      "WASM": 1,
      "NO_EXIT_RUNTIME": 1,
      "NO_FILESYSTEM": 1,
      "TOTAL_MEMORY": 157286400,
      "ALLOW_MEMORY_GROWTH": 1,
      "DEMANGLE_SUPPORT": 1,
      "EXTRA_EXPORTED_RUNTIME_METHODS": ["ccall"]
    }

    Maybe @kripken can chime in and shed some light on this.

  2. Thanks for coming by, Alon. As far as I understand, what Webpack team is trying to accomplish is ability to literally import .wasm file and have it work out of the box. No strings attached.

    Like so:

    import('./add.wasm').then(({ add }) => {
        console.log(add(22, 2200))
    })

    And really, code above will work when compiled with Webpack 4. But problem comes with complex modules like onigasm.wasm where the JavaScript runtime needs access to free, malloc, HEAPU8, etc. Thing is Webpack doesn’t provide those taps ATM. But this shouldn’t be hard since these are just function calls and access to few variables. The hard part is baking emcc compile flags into glue code that Webpack could generate on its own.

    Obviously that’s a very ambitious task. I think what you mentioned has much solid ground and ease of use:

    emscripten can emit that JS as a module (the MODULARIZE option, and soon, also as an ES6 module too). So my first thought is, can we use that JS like you’d use any other module, publish it on npm

    ^^ That right there IS what I’d happily take any day. The only problem?? Webpack import graph will ultimately reach [lib_name].wasm file:

    app.js imports
    node_modules/[lib_name]/glue.js imports
    node_modules/[lib_name]/bin/[lib_name].wasm

    When that happens, Webpack’s WebAssembly parser will find imports in WASM module that it can’t figure out, one of which is env. And then it explodes and build fails.

    That’s the challenge if go the regular ES6 based javascript glue route. The WASM imports that Webpack can’t understand/provide.

Comments are closed.