Using web workers in CRA

이제 더이상 Create-react-app 에서 웹워커 지원 안해요 라는 말은 없는 것으로.

1. Install CRA

$ npx create-react-app hello-worker-with-cra
...

$ cd hello-worker-with-cra

2. Install webpack worker plugin with react-app-rewired

$ yarn add --dev react-app-rewired worker-plugin
...
{
  ...
    
  "scripts": {
    ...
        
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    ...
  },
  ...
}
hello-worker-with-cra/package.json
const WorkerPlugin = require("worker-plugin");

module.exports = function override(config, env) {
  //do stuff with the webpack config...
  config.plugins.push(new WorkerPlugin());

  return config;
};
hello-worker-with-cra/config-overrides.js

3. Install worker and test

(example 1)

import { exposeWorker } from "react-hooks-worker";

const fib = (i) => (i <= 1 ? i : fib(i - 1) + fib(i - 2));

exposeWorker(fib);
hello-worker-with-cra/src/workers/slow_fib.worker.js
import { useWorker } from "react-hooks-worker";

...

const createWorker = () =>
  new Worker("./workers/slow_fib.worker", { type: "module" });
  
function App() {
  const { result, error } = useWorker(createWorker, 3);
  if (error) return <div>Error: {error}</div>;

  return (<div>Result: {result}</div>);
}

export default App;
hello-worker-with-cra/src/App.js

(example 2)

const fib = (i) => (i <= 1 ? i : fib(i - 1) + fib(i - 2));

onmessage = (evt) => {
  postMessage(fib(evt.data));
};
hello-worker-with-cra/src/workers/slow_fib.worker.js
const createWorker = () =>
  new Worker("./workers/slow_fib.worker", { type: "module" });
  
function App() {
  const worker = useRef(createWorker());
  const [result, setResult] = useState();

  useEffect(() => {
    worker.current.postMessage(7);

    worker.current.addEventListener("message", (evt) => {
      setResult(evt.data);
    });
  }, []);

  return (<div>Result: {result}</div>);
}

export default App;
hello-worker-with-cra/src/App.js