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!
Top comments (2)
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...
Let me grab another cup of coffee from,
i've been working all night for this problem. Thanks