How To Create Worker in React

Viewed 934

I'm trying to create a worker in an app created from create-react-app using react 16.8.6 and yarn 1.16.0. If I use const backgroundWorker = new Worker('../assets/js/myWorker.js');

I get the console error: Uncaught SyntaxError: Unexpected token <

But I know that is the correct path. This works fine in Angular. Is there a good tutorial on how to create a worker in React?

2 Answers

The directory "assets" is the public directory for @angular/cli projects, not create-react-app projects. In create-react-app the equivalent of @angular/cli "assets" is "public" which is described in the create-react-app documentation under Using the Public Folder. Move your "js" directory and the "myWorker.js" file to the public directory and update the creation of the worker to point to that path instead:

const backgroundWorker = new Worker('/js/myWorker.js');

You can also use process.env.PUBLIC_URL instead:

const backgroundWorker = new Worker(`${process.env.PUBLIC_URL}/js/myWorker.js`);

Hopefully that helps!

Follow these steps in order to add your worker files to your create-react-app project.

1. Install these three packages:

$ yarn add worker-plugin --dev
$ yarn add comlink
$ yarn add react-app-rewired --dev

2. Override webpack config:

In your project's root directory create a config-overrides.js file with the following content:

const WorkerPlugin = require("worker-plugin");

module.exports = function override(config, env) {
    //do stuff with the webpack config...

    config.plugins = [new WorkerPlugin({ globalObject: "this"}), ...config.plugins]
    return config;
}

3. Replace your npm scripts inside package.json by:

"start": "react-app-rewired start",
"build": "react-app-rewired build",

4. Create two files in order to test your configuration:

worker.js

import * as Comlink from "comlink";

class WorkerWorld {
  sayHello() {
    console.log("Hello! I am doing a heavy task.")
    let numbers = Array(500000).fill(5).map(num => num * 5);
    return numbers;
  }
}

Comlink.expose(WorkerWorld)

use-worker.js

import * as Comlink from "comlink";

const initWorker = async () => {
    const workerFile = new Worker("./worker", { name: "my-worker", type: "module" });
    const WorkerClass = Comlink.wrap(workerFile)

    const instance = await new WorkerClass();
    const result = await instance.sayHello();
    console.log("Result of my worker's computation: ", result);
}
initWorker()

5. See the output:

$ yarn start
Related