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]
},
]
}
};
Note, we need to change the following config:
- Change
output
to./public
folder so react-scripts can use it. - The
target
needs to bewebworker
. - Add
compilerOptions: {..., noEmit: false, ...}
tots-loader
options. This will overwrite thenoEmit:true
in thetsconfig.json
that created by create-react-app.
then, add a npm script to package.json and run it:
...
"worker": "webpack --watch",
...
And, in you app:
const worker = new Worker('worker.js');
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!
Oldest comments (2)
Let me grab another cup of coffee from,
i've been working all night for this problem. Thanks
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...