DEV Community

Anxiny
Anxiny

Posted on • Edited on

A simple way to use Web Worker with React-Create-APP - No eject needed

The problem of using Web Worker with an app that start with create-react-app is that:

  • create-react-app hide its webpack config from user to modify, if not ejected.
  • You need to modify webpack config in order to emit worker file.
  • If ejected, the webpack.config is overwhelming and hard to modify.
  • worker-loader is not very typescript-friendly.

A Solution

We can generator worker.js by running another webpack thread that only take care worker files. Here are what we need to do:

If you haven't install webpack-cli, you need to install it.

I'm using typescript, so let's install the ts-loader.

Then, add a webpack.config.js file at project root like this:

const path = require('path');
const webpack = require('webpack');

const src = path.resolve(__dirname, './src');
const build = path.resolve(__dirname, './public'); // output worker.js to public folder


const tsLoader = {
  loader: 'ts-loader',
  options: { compilerOptions: { module: 'esnext', noEmit: false } }
}


module.exports = {
  mode: 'none',
  target: "webworker", //Importan! Use webworker target
  entry: './src/worker.ts',
  output: {
    filename: 'worker.js',
    path: build
  },
  resolve: {
    modules: ["node_modules", src],
    extensions: [".js", ".json", ".jsx", ".ts", ".tsx"],
  },

  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('development') })
  ],
  module: {
    rules: [
      {
        test: /\.ts?$/,
        use: [tsLoader]
      },

    ]
  }
};

Enter fullscreen mode Exit fullscreen mode

Note, we need to change the following config:

  • Change output to ./public folder so react-scripts can use it.
  • The target needs to be webworker.
  • Add compilerOptions: {..., noEmit: false, ...} to ts-loader options. This will overwrite the noEmit:true in the tsconfig.json that created by create-react-app.

then, add a npm script to package.json and run it:

...
 "worker": "webpack --watch",
...
Enter fullscreen mode Exit fullscreen mode

And, in you app:

const worker = new Worker('worker.js');
Enter fullscreen mode Exit fullscreen mode

Now, start your react app and enjoy your worker.

PS:

I know this solution is not the best one, if you have any other suggestion, please leave a comment and let me know. Thanks!

Top comments (2)

Collapse
 
cyrfer profile image
John Grant

This guy makes it seem like it is built into Create React App. He provides a .ts file to Worker's URL.
blog.logrocket.com/web-workers-rea...

Collapse
 
ndotie profile image
ndotie

Let me grab another cup of coffee from,
i've been working all night for this problem. Thanks