DEV Community

Anxiny
Anxiny

Posted on • Edited on

5 3

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!

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

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

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay