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

Integrating with create-react-app #3

Closed
cimi opened this issue Jul 24, 2017 · 7 comments

Comments

@cimi
Copy link

commented Jul 24, 2017

I'm trying to use wasm-loader with create-react-app and I'm having some trouble getting it to work.

I'm using react-app-rewired to override the configuration:

module.exports = function override(config, env) {
  config.module.rules.push({
    test: /\.wasm$/,
    include: '/code/wasm-test/src',
    use: [require.resolve('wasm-loader')]
  });
  config.module.rules.forEach(rule => console.dir(rule));
  return config;
}

I've tried several different variants of this, got the same result for all of them (instead of use, reference loader directly, have an object with loader and options inside use, omit include).

The registration seems to work fine, and checking the output from the rules it seems that the rule for wasm-loader is added correctly:

{ test: /\.(js|jsx)$/,
  enforce: 'pre',
  use:
   [ { options: [Object],
       loader: '/code/wasm-test/node_modules/eslint-loader/index.js' } ],
  include: '/code/wasm-test/src' }
{ exclude:
   [ /\.html$/,
     /\.(js|jsx)$/,
     /\.css$/,
     /\.json$/,
     /\.bmp$/,
     /\.gif$/,
     /\.jpe?g$/,
     /\.png$/ ],
  loader: '/code/wasm-test/node_modules/file-loader/index.js',
  options: { name: 'static/media/[name].[hash:8].[ext]' } }
{ test: [ /\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/ ],
  loader: '/code/wasm-test/node_modules/url-loader/index.js',
  options: { limit: 10000, name: 'static/media/[name].[hash:8].[ext]' } }
{ test: /\.(js|jsx)$/,
  include: '/code/wasm-test/src',
  loader: '/code/wasm-test/node_modules/babel-loader/lib/index.js',
  options:
   { babelrc: false,
     presets: [ '/code/wasm-test/node_modules/babel-preset-react-app/index.js' ],
     cacheDirectory: true } }
{ test: /\.css$/,
  use:
   [ '/code/wasm-test/node_modules/style-loader/index.js',
     { loader: '/code/wasm-test/node_modules/css-loader/index.js',
       options: [Object] },
     { loader: '/code/wasm-test/node_modules/postcss-loader/lib/index.js',
       options: [Object] } ] }
{ test: /\.wasm$/,
  use: [ '/code/wasm-test/node_modules/wasm-loader/index.js' ] }

However, when trying to load wasm files I get not found failures:

import Counter from './wasm/counter';
// import fails on module not found
// if I replace with './wasm/counter.wasm' I get the file name as the value of the import
// non-existent file names (e.g. './wasm/counter2.wasm') also trigger not found, as expected
const wasmHelloWorld = () => {
  console.dir(Counter);    
}
window.onload = wasmHelloWorld;

Any idea what might be the issue?

Thanks for building this by the way, I can see it being really useful!

@cimi

This comment has been minimized.

Copy link
Author

commented Jul 24, 2017

I managed to get it working by adding the .wasm extension to config.resolve.extensions and adding the wasm rule to the fileLoader exclusions. I ended up with this in config-overrides.js:

// through this file we can override the default cra configuration
// see: https://github.com/timarney/react-app-rewired
const path = require('path')

module.exports = function override(config, env) {
  const wasmExtensionRegExp = /\.wasm$/;

  config.resolve.extensions.push('.wasm');
  // make the file loader ignore wasm files
  const fileLoader = config.module.rules
    .find(rule => rule.loader && rule.loader.endsWith(`${path.sep}file-loader${path.sep}index.js`));
  fileLoader.exclude.push(wasmExtensionRegExp);

  // and add a dedicated loader for them
  config.module.rules.push({
    test: wasmExtensionRegExp,
    include: path.resolve(__dirname, "src"),
    use: [{loader: require.resolve('wasm-loader'), options: {}}]
  });
  return config;
}

Now I'm hitting another issue (Chrome 59):

WebAssembly.Compile is disallowed on the main thread, if the buffer size is larger than 4KB. Use WebAssembly.compile, or compile on a worker thread.

This seems to be unrelated to the loader, so resolving this issue.

@cimi cimi closed this Jul 24, 2017

@DanielRamosAcosta

This comment has been minimized.

Copy link

commented Nov 26, 2018

@cimi I'm having this error:

./src/wasm/testingwasm.wasm
Module parse failed: magic header not detected
You may need an appropriate loader to handle this file type.
Error: magic header not detected

Any ideas?

@ballercat

This comment has been minimized.

Copy link
Owner

commented Nov 27, 2018

Sounds like a corrupted module. It could happen because of a number of different reasons.

wabt the WebAssembly binary toolkit has a few very useful tools available online, one of which allows you to upload a wasm module, validate it and convert to the text format: wasm2wat.

Upload your file there to test whether or not the file is actually valid to begin with.

@AThilenius

This comment has been minimized.

Copy link

commented Feb 2, 2019

I spent forever looking or a solution to this, so hoping this saves someone some time. New version of CRA seems to have rearranged the file-loader rule. My hack is:

// through this file we can override the default cra configuration
// see: https://github.com/timarney/react-app-rewired
const path = require('path');

module.exports = function override(config, env) {
  const wasmExtensionRegExp = /\.wasm$/;

  config.resolve.extensions.push('.wasm');
  // make the file loader ignore wasm files
  let fileLoader = null;
  config.module.rules.forEach(rule => {
    (rule.oneOf || []).map(oneOf => {
      if (oneOf.loader && oneOf.loader.indexOf('file-loader') >= 0) {
        fileLoader = oneOf;
      }
    });
  });
  fileLoader.exclude.push(wasmExtensionRegExp);

  // Add a dedicated loader for them
  config.module.rules.push({
    test: wasmExtensionRegExp,
    include: path.resolve(__dirname, 'src'),
    use: [{ loader: require.resolve('wasm-loader'), options: {} }],
  });
  return config;
};

Note: that needs to go into config-overrides.js, same dir as package.json. You also need to npm install --save-dev react-app-rewired and replace the scripts in package.json:

    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",

I read a bit that CRA 2+ can do this, so unsure if react-app-rewired is strictly necessary?


For building WASM that can be consumed, easiest way is to use wasm-pack, which will create a pkg directory. I put all the Rust stuff off the root dir into native. Then in package.json you can import pkg (which is a npm module) via:

  "dependencies": {
    "native": "file:../native/pkg",
  }

Finally, this must be async loaded, so my index.tsx is:

// The wasm must load async. Just wait to load anything else until it's done.
async function loadNative() {
  await import('native');
  await import('./app');
}

loadNative();
@prichey

This comment has been minimized.

Copy link

commented Mar 4, 2019

This blog post might be helpful for future visitors (using @AThilenius' answer above!): https://prestonrichey.com/blog/react-rust-wasm/

@yw662

This comment has been minimized.

Copy link

commented Mar 6, 2019

I encountered with

> react-app-rewired start
Starting the development server...

Failed to decode custom "name" section @50458; ignoring (integer representation too long).
Failed to compile.

./recognizer/pkg/recognizer_bg.wasm
Module parse failed: Unexpected section: 0x86
You may need an appropriate loader to handle this file type.
Error: Unexpected section: 0x86

I am following @prichey 's solution
The .wasm file is valid, can be disasm into .wast, and can be compiled directly in browser.
what should I do now ?

@yw662

This comment has been minimized.

Copy link

commented Mar 6, 2019

seems this is related to version issue of wasm-bindgen. change the line to =0.2.34 and it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants
You can’t perform that action at this time.