Search code examples
reactjswebassembly

WASM react module parse failed: magic header not detected


I'm trying to load a simple web assembly module in a react project. The wasm module was compiled with the MODULARIZE option.

From the documentation I've tried incorporating this into my code as follows:

fetch('./my-library.wasm')
  .then(response => response.arrayBuffer())
  .then(bytes => WebAssembly.instantiate(bytes))
  .then(results => {
    console.log("do something");
  });

Where ideally I would like to store the results in the state so I can access the module throughout the code (replacing the console log).

Unfortunately this gives me the error

Unhandled Rejection (CompileError): wasm validation error: at offset 4: failed to match magic number

What am I missing? Compiling without MODULARIZE also gives this error.


Solution

  • I tried this and this with my module but they didn't work so tried putting the wasm file directly in the public folder and fetching it from there (see also: this). It needed some tweaking specific to the use-case of the wasm module (memory settings, etc). My specific case looks like this now

    componentDidMount() {
      this.loadWasm();
    }
    
    loadWasm() {
      const path = process.env.PUBLIC_URL + '/my-library.wasm';
      const importObject = {
        env: {
          memoryBase: 0,
          tableBase: 0,
          memory: new WebAssembly.Memory({initial: 256, maximum: 1024}),
          table: new WebAssembly.Table({initial: 256, element: 'anyfunc'}),
          __assert_fail: function() {
            // todo
          },
          emscripten_resize_heap: function() {
            // todo
          },
          emscripten_memcpy_big: function() {
            // todo
          },
          setTempRet0: function() {
            // todo
          }
        }
      };
      WebAssembly.instantiateStreaming(fetch(path), importObject).then(obj => {
        // do stuff
      });
    }
    

    EDIT

    I was getting the magic number error when fetching the wasm from its javascript wrapper (e.g. a.out.js) because of a routing problem with react. At the end of it all I decided it was less of a hassle to just include the javascript as a dependency in the index.html file. This has the advantage of not having to mess with webpack and webpack non messing with the emcc-generated js. Also, not loading the wasm module directly, the emcc-generated js takes care of setting the importObject.