All Projects → dominique-mueller → create-react-app-typescript-web-worker-setup

dominique-mueller / create-react-app-typescript-web-worker-setup

Licence: MIT License
Using Web Workers in a TypeScript React project based on create-react-app.

Programming Languages

typescript
32286 projects
HTML
75241 projects
CSS
56736 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to create-react-app-typescript-web-worker-setup

truffle-react
⚛️ A boilerplate Truffle Box project with Create React App for rapid Ethereum Dapp development
Stars: ✭ 45 (+114.29%)
Mutual labels:  create-react-app
purescript-workers
An API wrapper around Web Workers (Dedicated, Shared and Service)
Stars: ✭ 24 (+14.29%)
Mutual labels:  web-worker
create-hyperapp
Create Hyperapps with no build configuration
Stars: ✭ 16 (-23.81%)
Mutual labels:  create-react-app
eslint-config-website
GUI for generating ESLint configs
Stars: ✭ 45 (+114.29%)
Mutual labels:  create-react-app
opPortfolio
A clean portfolio template made with ReactJS.
Stars: ✭ 29 (+38.1%)
Mutual labels:  create-react-app
react-intl-po-example
👉 This is a standalone project for using react-intl-po with CRA.
Stars: ✭ 38 (+80.95%)
Mutual labels:  create-react-app
graphyne
⚡ Lightning-fast JavaScript GraphQL Server ⚡
Stars: ✭ 18 (-14.29%)
Mutual labels:  web-worker
react-hot-reload.macro
Zero configuration 🔥Hot Module Replacement🔥 using Babel macro
Stars: ✭ 31 (+47.62%)
Mutual labels:  create-react-app
react-shopping-cart-demo
Notes and the code for the React.js crash course by Mosh Hamedani.
Stars: ✭ 86 (+309.52%)
Mutual labels:  create-react-app
react-firebase-t3chfest
T3chFest 2017 Workshop about React + Firebase
Stars: ✭ 42 (+100%)
Mutual labels:  create-react-app
templates
Templates for Intility developers.
Stars: ✭ 31 (+47.62%)
Mutual labels:  create-react-app
create-react-app-relay-modern
Create React App + Relay Modern
Stars: ✭ 50 (+138.1%)
Mutual labels:  create-react-app
epee-react-admin
🗡简洁、高效、易扩展的 React 快速开发模板,基于布局设计,纯 Hooks 开发,包含中后台应用常用功能
Stars: ✭ 87 (+314.29%)
Mutual labels:  create-react-app
linkedin-clone-react-frontend
🚀 Frontend for a software similar to LinkedIn
Stars: ✭ 48 (+128.57%)
Mutual labels:  create-react-app
chatty
A React single-page-application alternative client for the shacknews chatty.
Stars: ✭ 27 (+28.57%)
Mutual labels:  create-react-app
over-hangman
💥 Over powered hangman game
Stars: ✭ 42 (+100%)
Mutual labels:  create-react-app
react-app-rewire-workbox
Customise the service worker for create-react-app apps without ejecting - using Google's Workbox webpack plugins instead of the old sw-precache
Stars: ✭ 44 (+109.52%)
Mutual labels:  create-react-app
tmpnote
🍒 Share self-destructing encrypted notes
Stars: ✭ 22 (+4.76%)
Mutual labels:  create-react-app
react-mui-pro-starter
Mix of Create React App and Material UI with set of reusable components and utilities to build professional React Applications faster.
Stars: ✭ 14 (-33.33%)
Mutual labels:  create-react-app
rocketact
🚀Developing React projects with ease
Stars: ✭ 45 (+114.29%)
Mutual labels:  create-react-app

create-react-app-typescript-web-worker-setup

Using Web Workers in a TypeScript React project based on create-react-app.




How to use Web Workers in a TypeScript React app

This project is an example React application that uses Web Workers. You can clone it and play around with it (see Commands). The following sub-chapters explain how to setup Web Worker support in a create-react-app project, and how to use Web Workers in your app - both vanilla and using Comlink.


1. Install dependencies

First of all, we need a few new dependencies. In particular:

  • We need react-app-rewired to hook into the Webpack configuration that react-scripts uses under the hood (without having to eject the config)
  • We use the Webpack worker-loader to integrate Web Workers into our build process

Add both dependencies to your package.json file and install them. For example:

  {
    "devDependencies": {
+     "react-app-rewired": "2.1.x",
+     "worker-loader": "3.0.x"
    }
  }

2. Customize the build process

First, replace all mentions of react-scripts within the scripts area of your package.json file by react-app-rewired. This enables us to tap into the build process in the next step. For example:

  {
    "scripts": {
-     "start": "react-scripts start",
+     "start": "react-app-rewired start",
-     "build": "react-scripts build",
+     "build": "react-app-rewired build",
-     "test": "react-scripts test",
+     "test": "react-app-rewired test",
    }
  }

Then, create a file named react-app-rewired.config.js (or whatever name you prefer) within the root folder of your project. This file will be used by react-app-rewired when the build process runs, and allows us to customize the underlying Webpack configuration before the build runs. Fill it with the following content:

/**
 * React App Rewired Config
 */
module.exports = {
  // Update webpack config to use custom loader for worker files
  webpack: (config) => {
    // Note: It's important that the "worker-loader" gets defined BEFORE the TypeScript loader!
    config.module.rules.unshift({
      test: /\.worker\.ts$/,
      use: {
        loader: 'worker-loader',
        options: {
          // Use directory structure & typical names of chunks produces by "react-scripts"
          filename: 'static/js/[name].[contenthash:8].js',
        },
      },
    });

    return config;
  },
};

Finally, reference the react-app-rewired.config.js file in your package.json file by adding the following line:

  {
+   "config-overrides-path": "react-app-rewired.config.js",
  }

3. Create and use a Web Worker

Now you can start using Web Workers! Two things are important here: Files that contain a Web Worker must end with *.worker.ts, and they must start with the following two lines of code in order to work nicely together with TypeScript:

declare const self: DedicatedWorkerGlobalScope;
export default {} as typeof Worker & { new (): Worker };

// Your code ...

In your application, you can import your Web Workers like a normal module, and instantiate them as a class. For example:

import MyWorker from './MyWorker.worker';

const myWorkerInstance: Worker = new MyWorker();

Implementation pointers:


Bonus: Using Comlink

Using Web Workers as is comes with the additional overhead of messaging between the main thread and the worker thread. Comlink is a library by Googlers that simplifies the usage of Web Workers by turning the message-based communication into a "remote function execution"-like system.

Within your React app, you can use Comlink just like you would expect. For example, expose your API within your worker:

import { expose } from 'comlink';

export default {} as typeof Worker & { new (): Worker };

// Define API
export const api = {
  createMessage: (name: string): string => {
    return `Hello ${name}!`;
  },
};

// Expose API
expose(api);

Then, from within you main thread, wrap the instantiated worker and use the worker API (asynchronously):

import { wrap } from 'comlink';
import MyComlinkWorker, { api } from './MyComlinkWorker.worker';

// Instantiate worker
const myComlinkWorkerInstance: Worker = new MyComlinkWorker();
const myComlinkWorkerApi = wrap<typeof api>(myComlinkWorkerInstance);

// Call function in worker
myComlinkWorkerApi.createMessage('John Doe').then((message: string) => {
  console.log(message);
});

Implementation pointers:


A note on testing

Soooo, Jest does not support Web Workers (see jest/#3449). Plus, Jest does not use our customized Webpack configuration anyways. Thus - using one of the many ways you can mock stuff in Jest - mock away Web Workers when testing code that instantes them / works with them.



Commands

The following commands are available:

Command Description CI
npm start Creates a development build, running in watch mode
npm run build Creates a production build ✔️
npm run start:build Runs the production build
npm run test Executes all unit tests ✔️
npm run test:watch Executes all unit tests, running in watch mode
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].