Open dansiviter opened 6 years ago
For anyone using react-app-rewired
who wants to have both React Refresh and Web Workers:
$ yarn add --dev customize-cra @pmmmwh/react-refresh-webpack-plugin react-refresh
// config-overrides.js
const {
override,
addBabelPlugin, getBabelLoader,
addWebpackPlugin, addWebpackModuleRule,
} = require('customize-cra')
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
module.exports = (config, env) => {
const prod = config.mode === 'production'
const babelLoader = getBabelLoader(config)
return override(
// You can choose to just use worker-loader! instead if you want
addWebpackModuleRule({
test: /\.worker\.[jt]sx?$/,
use: [
{ loader: 'worker-loader' },
{ loader: babelLoader.loader, options: babelLoader.options },
],
}),
!prod && addBabelPlugin('react-refresh/babel'),
!prod && addWebpackPlugin(new ReactRefreshPlugin()),
)(config, env)
}
Then in your app:
import MyWorker from './test.worker.js'
const worker = new MyWorker()
worker.onmessage = evt => console.log(evt.data)
This method allows you to use imports etc. within your worker, and it will be hot-reloaded. Note that the worker will be placed in its own chunk and fetched asynchronously - no need to use dynamic import.
For TypeScript:
// Add to react-app-env.d.ts
declare module '*.worker.ts' {
class WebpackWorker extends Worker {
constructor()
}
export default WebpackWorker
}
import MyWorker from './test.worker.ts' // .ts extension is required!
This works fine!
small clarification
// public/worker.js // some worker
// src/index.js const getPathFromPublic = path => `${process.env.PUBLIC_URL}/${path}`; const workerPath = getPathFromPublic('worker.js'); const worker = new Worker(workerPath);
However, can you put the worker.js
file in /src
and prevent its minification/transpilation by another way?
If anyone is looking for a solution with Typescript, you could try with react-app-rewired
. Here you are the code working:
https://github.com/educartoons/creact-react-app-typescript-web-workers
It generates the build folder properly.
🍎
@NicolasRannou thanks for sharing your experience!
works fine for me as well and I am super happy that don't need to eject
or use react-app-rewired
hacks.
up!
+1 for Audio worklets, createScriptProcessor
is deprecated so at some point we'll be unable to record audio without support for them.
Thanks for the tip @NicolasRannou! (https://github.com/facebook/create-react-app/issues/3660#issuecomment-603922095)
In case it helps anyone, I've used this tip to set up a create-react-app typescript demonstration application with the minimum configuration necessary to consume Web Workers using Comlink: https://github.com/FLGMwt/comlink-web-worker-in-create-react-app. I couldn't get it to work importing the project through CodeSandbox, but you can try it out here: https://comlink-web-worker-in-create-react-app.netlify.app/
Version 5 of create-react-app added support for webpack 5. webpack 5 added support for webworkers. This works for my use case and hopefully for the others! Now to figure out how to mock/inject into jest tests...
ref to APP PixelShapeRN commit react -> react-native: let Web Worker with Support for CRA v5 (and Webpack 5) and doc Upgrade to react-scripts@5 and Add Web Workers support
Add ability to load WebWorkers (and SharedWorkers?) via the react-scripts. My use-case is for using latency (and debug) sensitive protocols over WebSocket which may get dumped by the server if no activity occurs.
There has been a lot of discussion regarding this on #1277 but no definitive answer and now closed. Also, I'm a server-side dev so JavaScript PR is not my forte, and neither is ejecting the scripts as that looks scary.