React: Unterschied zwischen den Versionen

Aus CodicaTipps
Zur Navigation springen Zur Suche springen
 
(51 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 7: Zeile 7:
 
Siehe  
 
Siehe  
 
* [https://www.robinwieruch.de/react-pass-props-to-component/ Vertiefung der React Props] - ausführlich unter Berücksichtigung neuerer JavaScript-Sprachkonstrukte
 
* [https://www.robinwieruch.de/react-pass-props-to-component/ Vertiefung der React Props] - ausführlich unter Berücksichtigung neuerer JavaScript-Sprachkonstrukte
 +
 +
=== React Native ===
 +
 +
Seihe [[React Native]]
  
 
== Projektstruktur ==
 
== Projektstruktur ==
  
 
React gibt keine Projektstruktur vor. Mit Hilfe von [https://github.com/facebook/create-react-app Create-react-app] kann jedoch eine Grundstruktur erzeugt werden, die von vielen React-Projekten verwendet wird. Dadurch können sich fremde Entwickler leicht darin zurecht finden.
 
React gibt keine Projektstruktur vor. Mit Hilfe von [https://github.com/facebook/create-react-app Create-react-app] kann jedoch eine Grundstruktur erzeugt werden, die von vielen React-Projekten verwendet wird. Dadurch können sich fremde Entwickler leicht darin zurecht finden.
 +
 +
Siehe für eine Projektstruktur mit frontend-, backend- und shared-Quellcode auch
 +
* https://blog.codecentric.de/2019/05/web-anwendungen-mit-node-express-typescript-entwickeln/
 +
 +
=== Alternative zu create-react-app ===
 +
 +
Einen schnelleren Build-Prozess als create-react-app aufgrund des eingesetzten esbuild-Tools verspricht Vite.
 +
 +
* [https://dev.to/nilanth/use-vite-for-react-apps-instead-of-cra-3pkg nilanth zeigt u.a. den Migrationsprozess von CRA zu Vite]
 +
 +
Auch Parcel ist eine Alternative zu [[webpack]], dem Bundler-Tool von create-react-app. Siehe
 +
* https://adrianhall.github.io/javascript/react/2020/03/29/parcel-typescript-react/ - Teil 1
 +
* https://adrianhall.github.io/javascript/react/2020/03/31/adding-storybook-to-template/ - Teil 2: mit StoryBook
 +
* https://adrianhall.github.io/javascript/react/2020/04/02/adding-unit-testing-to-template/ - Teil 3: Jest mit Enzyme
 +
* https://github.com/adrianhall/parcel-typescript-template/tree/main - die fertige Schablone für ein Parcel, TypeScript, React, Jest, StoryBook - Projekt
 +
 +
=== Auslieferung von relativer Serveradresse ===
 +
 +
Siehe
 +
* https://stackoverflow.com/questions/43011207/using-homepage-in-package-json-without-messing-up-paths-for-localhost
  
 
== React und TypeScript und Webpack ==
 
== React und TypeScript und Webpack ==
 
+
=== Allgemeines ===
 
Siehe
 
Siehe
 
* Codeburst on webpack typescript and react
 
* Codeburst on webpack typescript and react
Zeile 19: Zeile 43:
 
** https://codeburst.io/webpack-typescript-react-part-3-82ce3000d25e
 
** https://codeburst.io/webpack-typescript-react-part-3-82ce3000d25e
  
== React und TypeScript und Redux ==
+
=== Server Side Rendering ===
 +
 
 +
Für Server Side Rendering (SSR) oder Static Site Generation, ggf. mit späterer Hydration durch dynamische React-Elemente, gibt es
 +
* cra-ssr (wohl veraltet)
 +
* [https://github.com/stereobooster/react-snap react-snap] - arbeitet mit einem Headless Chrome im Build-Prozess
 +
* [https://github.com/dzianisbohush/cra-with-ssr cra-with-ssr Anleitung zu SSR mit Hydration auf Basis von CRA]
 +
* [https://razzlejs.org/docs/static-export Razzle]
 +
* umfangreichere Frameworks
 +
** Next.js
 +
** Vite
 +
** [https://remix.run/ Remix]
 +
** [https://www.gatsbyjs.com/ Gatsby]
 +
*** https://medium.com/@thetrevorharmon/how-to-make-a-super-fast-static-site-with-gatsby-typescript-and-sass-3742c00d4524
 +
 
 +
Als CMS-Backend z.B. für Gatsby gibt es u.a.
 +
* strapi
 +
 
 +
== React und global state management nach dem Flux-Prinzip ==
 +
=== React und TypeScript und Redux ===
 
* https://www.typescriptlang.org/docs/handbook/react-&-webpack.html
 
* https://www.typescriptlang.org/docs/handbook/react-&-webpack.html
 
* https://medium.com/better-programming/react-redux-with-typescript-7ff678bc17ab
 
* https://medium.com/better-programming/react-redux-with-typescript-7ff678bc17ab
Zeile 25: Zeile 67:
 
* [https://github.com/piotrwitek/react-redux-typescript-guide Kompendium zu React, TypeScript und Redux]
 
* [https://github.com/piotrwitek/react-redux-typescript-guide Kompendium zu React, TypeScript und Redux]
 
* [https://medium.com/@dhruvrajvanshi/some-tips-on-type-safety-with-redux-98588a85604c Vorschlag einer Best Practice für Typensicherheit mit Redux und React]
 
* [https://medium.com/@dhruvrajvanshi/some-tips-on-type-safety-with-redux-98588a85604c Vorschlag einer Best Practice für Typensicherheit mit Redux und React]
 +
 +
=== Leichtgewichtige Alternativen ===
 +
 +
==== Eigene (custom) react hooks ====
 +
 +
Siehe
 +
* [https://blog.logrocket.com/react-hooks-with-firebase-firestore/ Erläuterung zur Nutzung von React Hooks] zur Kapselung der Logik, um eine Status-ID mit einem URL-Query-Parameter zu synchronisieren.
 +
 +
==== global hook store ====
 +
Mit [https://www.npmjs.com/package/global-hook-store global-hook-store] hat man eine leichtgewichtige Alternative zu Redux, die [[React Hooks]] nutzt und [[TypeScript]]-Support gleich mitbringt.
 +
Wenn man [[create-react-app]] mit [[TypeScript]]-Vorlage verwendet, kommt es bei den [[Jest]]-Unit-Tests zu Problemen. Dann hilft es, in die <code>package.json</code> Folgendes aufzunehmen:
 +
<pre>
 +
 +
  "jest": {
 +
    "transformIgnorePatterns": [
 +
      "/node_modules/(?!global-hook-store).+\\.js$"
 +
    ]
 +
  },
 +
</pre>
 +
 +
==== Dai Shis React Hooks Global State ====
 +
 +
Dai Shi hat https://github.com/dai-shi/react-hooks-global-state implementiert
 +
 +
==== HookState.js ====
 +
 +
Siehe https://hookstate.js.org/docs/getting-started/
 +
 +
==== Recoil ====
 +
 +
Siehe
 +
* https://recoiljs.org/
 +
 +
 +
==== Jotai ====
 +
 +
Siehe
 +
 +
* https://github.com/pmndrs/jotai
  
 
== Testen von React ==
 
== Testen von React ==
Zeile 42: Zeile 123:
  
 
== Ergänzungen für React ==
 
== Ergänzungen für React ==
 +
=== Adresszeile ===
 +
 +
Die Standardergänzung, um mit der Adresszeile zu arbeiten, ist für React der React Router.
 +
 +
Aber es gibt auch andere Ergänzungen
 +
* [https://www.npmjs.com/package/react-query-params React-Query-Params] lässt mit den URI-Parametern ähnlich umgehen wie mit State oder Props.
 +
 
=== Komponenten ===
 
=== Komponenten ===
  
 
==== Rich Text Editor ====
 
==== Rich Text Editor ====
  
* Der CKEditor unterstützt u.a. Tabellen. Ihn gibt es auch in einem React-Geschmack.
+
* [https://github.com/ianstormtaylor/slate Slate]
 +
* [https://craft.js.org/r/docs/guides/basic-tutorial Craft.js]
 +
 
 +
* Der CKEditor unterstützt u.a. Tabellen.  
 +
** Ihn gibt es auch in einem [https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/react.html React-Geschmack].
 +
** Der [https://alloyeditor.com/docs/features/tableheading.html AlloyEditor] macht sich Mühe, ihn mit kontextsensitiven Menüs auszugestalten.
 +
* Den [https://www.tiny.cloud/pricing TinyMCE] gibt es in einer Open Source- und verschiedenen kommerziellen Varianten.
 +
** [https://www.tiny.cloud/docs/integrations/react/ TinyMCE-React Integration]
 +
* [https://xdsoft.net/jodit/ Jodit] kann auch [https://xdsoft.net/jodit/play.html Tabellen].
 +
** https://github.com/jodit/jodit-react (MIT Lizenz)
 +
* https://github.com/mkhstar/suneditor-react
 +
* https://github.com/summernote/summernote
 +
** https://github.com/summernote/react-summernote
 +
* https://www.npmjs.com/package/react-editor-js unterstützt auch einfache Tabellen
 +
 
 +
* [https://react-page.github.io/ React Page] hat wohl keine Tabellen.
 +
* https://github.com/zenoamaro/react-quill hat wohl keine Tabellen.
 +
 
 +
* https://github.com/quilljs/quill
 +
** https://github.com/quilljs/quill
 +
** https://github.com/zenoamaro/react-quill
 +
 
 
==== Komponentensammlung ====
 
==== Komponentensammlung ====
  
* [https://www.primefaces.org/primereact/#/ PrimeReact] bietet ca. 70 UI-Komponenten.
+
* [https://primereact.org/ PrimeReact] bietet sehr viele UI-Komponenten.
 +
** Das Schwesterprojekt [https://primeflex.org/ PrimeFlex] bietet CSS-Klassen.
 
* [https://github.com/carbon-design-system/carbon/tree/master/packages/react IBM Carbon Desgin]
 
* [https://github.com/carbon-design-system/carbon/tree/master/packages/react IBM Carbon Desgin]
 +
* [https://www.radix-ui.com/themes/playground Radix] benützt zumindest JSX, ist möglicherweise React-basiert
 +
* [https://ui.shadcn.com/ shadcn/ui] ist Radix-basiert.
 +
* [https://react.semantic-ui.com/ Semantic UI]
 +
** https://www.npmjs.com/package/react-semantic-ui-datepickers
 +
* [https://fomantic-ui.com/ Fomantic-UI] - ein Open Source Fork von Semantic UI
 +
 +
==== Icons ====
 +
 +
* https://github.com/feathericons/feather bietet einfache Icons im SVG-Format unter MIT-Lizenz
 +
** [https://feathericons.com/ Feather-Icon-Übersicht]
 +
** react-feather
 +
* [https://ionic.io/ionicons Ionicons] mit MIT-Lizenz
 +
* [https://github.com/phosphor-icons/phosphor-icons Phosphor-Icons] sind ebenfalls unter der MIT-Lizenz
 +
** [https://phosphoricons.com/ Phosphor-Icons-Übersicht]
 +
* [https://github.com/twbs/icons Bootstrap Icons] können unabhängig vom Rest von [[Bootstrap]] genutzt werden.
 +
** https://icons.getbootstrap.com/
 +
* [https://github.com/carbon-design-system/carbon/tree/master/packages/icons IBM Carbon Icons] mit Apache-Lizenz und React-Unterstützung
 +
** [https://carbon-elements.netlify.app/icons/examples/preview/ Carbon Icon Übersicht]
 +
* [https://iconify.design/icon-sets/ Übersicht über verschiedene Icon-Sets]
 +
 +
==== Diagramme ====
 +
 +
* [https://airbnb.io/visx/gallery VisX] ist eine umfangreiche React-basierte Bibliothek, um Daten graphisch darstellen zu können.
 +
* https://www.npmjs.com/package/react-minimal-pie-chart
  
 
=== Canvas und React ===
 
=== Canvas und React ===
Zeile 107: Zeile 241:
 
   cd "$PROJ_DIR"
 
   cd "$PROJ_DIR"
 
   npm start
 
   npm start
 +
 +
==== API-Requests im Entwicklungsmodus umlenken lassen ====
 +
 +
Um die AJAX-Zugriffe des Frontends während der Entwicklungsphase auf den API-Server umzulenken, nimmt man in die <code>frontend/package.json</code> etwa folgende Zeile auf:
 +
 +
  "proxy": "http://localhost:4000"
 +
 +
Der Entwicklungsserver muss dann auf dem Port 4000 laufen.
 +
 +
Siehe
 +
* https://create-react-app.dev/docs/proxying-api-requests-in-development/
  
 
=== Tests laufen lassen ===
 
=== Tests laufen lassen ===
Zeile 116: Zeile 261:
 
   npm run build
 
   npm run build
 
    
 
    
 +
=== create-react-app, TypeScript und WebWorkers ===
 +
 +
Wenn man seine mit <code>create-react-app --template typescript</code> erstellte Web-Applikation um Multithreading via Web Workers erweitern möchte, stellt sich das Problem, dass die Webpack-Konfiguration von create-react-app so komplex ist, dass man sie nicht anfassen möchte. Eine Änderung hätte auch Probleme mit dem Update der react-scripts zur Folge.
 +
 +
In Webpack v5 wird durch das URL-Handling von Webpack der Einsatz von TypeScript-WebWorkern [https://github.com/webpack/webpack/discussions/13655 mehr oder weniger einfach].
 +
  new Worker(new URL('./worker.js', import.meta.url));
 +
Möglicherweise muss man in der tsconfig.json jedoch [https://thewebdev.info/2022/03/21/how-to-make-web-workers-with-typescript-and-webpack/ in compilerOptions.lib "webworker" ] ergänzt werden.
 +
 +
Siehe zu Webpack5 auch:
 +
* https://blog.logrocket.com/web-workers-react-typescript/
 +
 +
Bisher nutzt man in Webpack v4 die "!"-Syntax von Webpack für das Laden des worker-loader aus. So kann man vorgehen:
 +
 +
==== Installation von worker-loader ====
 +
 +
  cd $PROJ_DIR
 +
  npm install worker-loader --save-dev
 +
 +
==== Typdeklaration für Typescript ====
 +
 +
Erstellen der Datei <code>$PROJ_DIR/src/typings/worker-loader.d.ts</code> mit folgendem Inhalt
 +
  declare module 'worker-loader!*' {
 +
    // You need to change `Worker`, if you specified a different value for the `workerType` option
 +
    class WebpackWorker extends Worker {
 +
      constructor();
 +
    }
 +
 +
    // Uncomment this if you set the `esModule` option to `false`
 +
    // export = WebpackWorker;
 +
    export default WebpackWorker;
 +
  }
 +
 +
==== Worker selbst ====
 +
 +
Erstellen der Datei <code>$PROJ_DIR/src/my.worker.ts</code> mit folgendem Inhalt<ref>Vgl. https://www.npmjs.com/package/worker-loader - es wurde ein import-Statement hinzugefügt.</ref>
 +
<pre>
 +
// Dieses Import-Statement ist nur notwendig, um dem Typescript-Transpiler mitzuteilen, dass
 +
// es sich hier auch um ein Module handelt. Es kann durch beliebige andere Imports ersetzt werden.
 +
import {} from "assert";
 +
// eslint-disable-next-line no-restricted-globals
 +
const ctx: Worker = self as any;
 +
 +
// Post data to parent thread
 +
ctx.postMessage({ foo: "foo" });
 +
 +
// Respond to message from parent thread
 +
ctx.addEventListener("message", (event) => {
 +
  console.log("message from main thread:", event);
 +
  ctx.postMessage({ orgData: event.data, now:new Date()})
 +
});
 +
</pre>
 +
 +
==== Aufruf des Workers vom Main-Thread ====
 +
 +
Im Main-Thread, z.B. in <code>$PROJ_DIR/src/App.tsx</code> kann man auf den Worker folgendermaßen zugreifen:
 +
 +
<pre>
 +
// eslint-disable-next-line import/no-webpack-loader-syntax
 +
import Worker from 'worker-loader!./my.worker';
 +
 +
const worker = new Worker();
 +
 +
worker.postMessage({ a: 1 });
 +
worker.onmessage = (event) => { console.log ("message from worker:", event)};
 +
</pre>
 +
 +
==== Weiterhin: Problem mit Development-Server ====
 +
 +
Wenn weiterhin ein Problem mit dem Entwicklungsserver (<code>npm run start</code>) besteht, hilft evtl. das Überschreiten der create-react-app-Konfiguration mit react-rewired:
 +
 +
* https://junghanns.it/posts/setup-workers-with-create-react-app-and-typescript/
 +
** Möglicherweise muss man dabei auch [https://github.com/webpack-contrib/worker-loader/issues/35#issuecomment-571034338 an Babel denken].
 +
 +
Aber mit bestimmten Kniffen (z.B. Kopieren des Workers nach /public) kann man auch das Modifizieren der Konfiguration vermeiden:
 +
* https://github.com/webisora/displaying-pdf-using-react
 +
 +
===== pdf.js =====
 +
 +
Beim pdf.js-Worker hilft evtl. pdf.js nicht über pdfjs-dist, sondern über react-pdf einzubinden
 +
 +
  npm install --save react-pdf
 +
  npm install --save-dev @types/pdfjs-dist
 +
  cp node_modules/pdfjs-dist/build/pdf.worker.js public/
 +
 +
Im TypeScript-Code müssen dann folgende Zeilen vorhanden sein:
 +
 +
  import * as PDFJS from "pdfjs-dist";
 +
 +
  PDFJS.GlobalWorkerOptions.workerSrc =
 +
      `${process.env.PUBLIC_URL}/pdf.worker.js`;
 +
 +
  PDFJS.getDocument(...
 +
 +
=== WebWorker und NextJs ===
 +
 +
Siehe oben "create-react-app, TypeScript und WebWorkers".
 +
 +
Siehe auch
 +
 +
* https://github.com/vercel/next.js/tree/canary/examples/with-web-worker
 +
** https://github.com/vercel/next.js/blob/canary/examples/with-web-worker/pages/index.tsx
 +
* https://nextjs.org/docs/messages/webpack5
 +
* https://github.com/koheitakumi/nextjs-typescript-comlink
 +
 +
==== WebWorker, WebAssembly and NextJs ====
 +
 +
Mit [[WebAssembly]] kann auch compilierter Rust-Code im Browser, auch als WebWorker, ausgeführt werden:
 +
 +
Siehe https://medium.com/lagierandlagier/nextjs-webassembly-and-web-workers-a5f7c19d4fd0
 +
 
=== Troubleshooting ===
 
=== Troubleshooting ===
  

Aktuelle Version vom 5. Juni 2024, 14:47 Uhr

React ist ein von Facebook entwickeltes Framework zum Darstellen von HTML-UI-Komponenten. Es gibt es auch in einem React Native-"Geschmack" zum Erstellen von nativen Android- oder iOS-Apps.

Allgemeines

Das Framework wird unter einer OpenSource-Lizenz verbreitet.

Siehe

React Native

Seihe React Native

Projektstruktur

React gibt keine Projektstruktur vor. Mit Hilfe von Create-react-app kann jedoch eine Grundstruktur erzeugt werden, die von vielen React-Projekten verwendet wird. Dadurch können sich fremde Entwickler leicht darin zurecht finden.

Siehe für eine Projektstruktur mit frontend-, backend- und shared-Quellcode auch

Alternative zu create-react-app

Einen schnelleren Build-Prozess als create-react-app aufgrund des eingesetzten esbuild-Tools verspricht Vite.

Auch Parcel ist eine Alternative zu webpack, dem Bundler-Tool von create-react-app. Siehe

Auslieferung von relativer Serveradresse

Siehe

React und TypeScript und Webpack

Allgemeines

Siehe

Server Side Rendering

Für Server Side Rendering (SSR) oder Static Site Generation, ggf. mit späterer Hydration durch dynamische React-Elemente, gibt es

Als CMS-Backend z.B. für Gatsby gibt es u.a.

  • strapi

React und global state management nach dem Flux-Prinzip

React und TypeScript und Redux

Leichtgewichtige Alternativen

Eigene (custom) react hooks

Siehe

global hook store

Mit global-hook-store hat man eine leichtgewichtige Alternative zu Redux, die React Hooks nutzt und TypeScript-Support gleich mitbringt. Wenn man create-react-app mit TypeScript-Vorlage verwendet, kommt es bei den Jest-Unit-Tests zu Problemen. Dann hilft es, in die package.json Folgendes aufzunehmen:


  "jest": {
    "transformIgnorePatterns": [
      "/node_modules/(?!global-hook-store).+\\.js$"
    ]
  },

Dai Shis React Hooks Global State

Dai Shi hat https://github.com/dai-shi/react-hooks-global-state implementiert

HookState.js

Siehe https://hookstate.js.org/docs/getting-started/

Recoil

Siehe


Jotai

Siehe

Testen von React

Siehe

Lange Listen in React

Siehe

Ergänzungen für React

Adresszeile

Die Standardergänzung, um mit der Adresszeile zu arbeiten, ist für React der React Router.

Aber es gibt auch andere Ergänzungen

  • React-Query-Params lässt mit den URI-Parametern ähnlich umgehen wie mit State oder Props.

Komponenten

Rich Text Editor

Komponentensammlung

Icons

Diagramme

Canvas und React

Siehe

Beispiel für TypeScript und React

Grundlegendes

Ein Projekt sollte ein Versionskontrollsystem nutzen. Ein früherer Zustand des Projekts sollte wiederhergestellt werden können. Zu diesem Zustand gehören grundsätzlich auch die Abhängigkeiten (wie externe Programmierbibliotheken).

Die folgenden Kommandozeilen setzen die Bash unter Linux oder MacOS voraus. Vieles davon dürfte - evtl. leicht modifiziert - auch auf Windows laufen.

Installation von node

Node.js kommt zwar mit der Linux-Distribution, aber wir wollen - um möglichst alle Abhängigkeiten zu definieren - mit Hilfe von nvm eine spezifische Node-Version installieren:

Im Terminal nvm-Repo klonen:

 cd ~
 git clone https://github.com/creationix/nvm.git .nvm
 cd .nvm

Folgende Zeilen an die ~/.bashrc anfügen:

 export NVM_DIR="$HOME/.nvm"
 [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
 [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion


Im Terminal node-LTS herunterladen und als Standard setzen:

 nvm install 'lts/*'
 nvm alias default 'lts/*'

Projekt initialisieren

Projektverzeichnis erstellen und für GIT initialisieren:

 export PROJ_DIR=~/myprojects/myproject
 mkdir "$PROJ_DIR"
 cd "$PROJ_DIR"
 git init

Die Datei .gitignore erstellen:

 frontend/node_modules

React-App-Verzeichnisstruktur erstellen (mit Typescript[1]):

 cd "$PROJ_DIR"
 npx create-react-app frontend --typescript

Projekt im Entwicklungsmodus starten

 cd "$PROJ_DIR"
 npm start

API-Requests im Entwicklungsmodus umlenken lassen

Um die AJAX-Zugriffe des Frontends während der Entwicklungsphase auf den API-Server umzulenken, nimmt man in die frontend/package.json etwa folgende Zeile auf:

 "proxy": "http://localhost:4000"

Der Entwicklungsserver muss dann auf dem Port 4000 laufen.

Siehe

Tests laufen lassen

 cd "$PROJ_DIR"
 npm test

Projekt bauen

 cd "$PROJ_DIR"
 npm run build
 

create-react-app, TypeScript und WebWorkers

Wenn man seine mit create-react-app --template typescript erstellte Web-Applikation um Multithreading via Web Workers erweitern möchte, stellt sich das Problem, dass die Webpack-Konfiguration von create-react-app so komplex ist, dass man sie nicht anfassen möchte. Eine Änderung hätte auch Probleme mit dem Update der react-scripts zur Folge.

In Webpack v5 wird durch das URL-Handling von Webpack der Einsatz von TypeScript-WebWorkern mehr oder weniger einfach.

 new Worker(new URL('./worker.js', import.meta.url));

Möglicherweise muss man in der tsconfig.json jedoch in compilerOptions.lib "webworker" ergänzt werden.

Siehe zu Webpack5 auch:

Bisher nutzt man in Webpack v4 die "!"-Syntax von Webpack für das Laden des worker-loader aus. So kann man vorgehen:

Installation von worker-loader

 cd $PROJ_DIR
 npm install worker-loader --save-dev

Typdeklaration für Typescript

Erstellen der Datei $PROJ_DIR/src/typings/worker-loader.d.ts mit folgendem Inhalt

 declare module 'worker-loader!*' {
   // You need to change `Worker`, if you specified a different value for the `workerType` option
   class WebpackWorker extends Worker {
     constructor();
   }

   // Uncomment this if you set the `esModule` option to `false`
   // export = WebpackWorker;
   export default WebpackWorker;
 }

Worker selbst

Erstellen der Datei $PROJ_DIR/src/my.worker.ts mit folgendem Inhalt[2]

// Dieses Import-Statement ist nur notwendig, um dem Typescript-Transpiler mitzuteilen, dass
// es sich hier auch um ein Module handelt. Es kann durch beliebige andere Imports ersetzt werden.
import {} from "assert";
// eslint-disable-next-line no-restricted-globals 
const ctx: Worker = self as any;

// Post data to parent thread
ctx.postMessage({ foo: "foo" });

// Respond to message from parent thread
ctx.addEventListener("message", (event) => {
  console.log("message from main thread:", event);
  ctx.postMessage({ orgData: event.data, now:new Date()})
});

Aufruf des Workers vom Main-Thread

Im Main-Thread, z.B. in $PROJ_DIR/src/App.tsx kann man auf den Worker folgendermaßen zugreifen:

// eslint-disable-next-line import/no-webpack-loader-syntax
import Worker from 'worker-loader!./my.worker';
 
const worker = new Worker();
 
worker.postMessage({ a: 1 });
worker.onmessage = (event) => { console.log ("message from worker:", event)};

Weiterhin: Problem mit Development-Server

Wenn weiterhin ein Problem mit dem Entwicklungsserver (npm run start) besteht, hilft evtl. das Überschreiten der create-react-app-Konfiguration mit react-rewired:

Aber mit bestimmten Kniffen (z.B. Kopieren des Workers nach /public) kann man auch das Modifizieren der Konfiguration vermeiden:

pdf.js

Beim pdf.js-Worker hilft evtl. pdf.js nicht über pdfjs-dist, sondern über react-pdf einzubinden

 npm install --save react-pdf
 npm install --save-dev @types/pdfjs-dist
 cp node_modules/pdfjs-dist/build/pdf.worker.js public/

Im TypeScript-Code müssen dann folgende Zeilen vorhanden sein:

 import * as PDFJS from "pdfjs-dist";
 PDFJS.GlobalWorkerOptions.workerSrc =
     `${process.env.PUBLIC_URL}/pdf.worker.js`;
 PDFJS.getDocument(...

WebWorker und NextJs

Siehe oben "create-react-app, TypeScript und WebWorkers".

Siehe auch

WebWorker, WebAssembly and NextJs

Mit WebAssembly kann auch compilierter Rust-Code im Browser, auch als WebWorker, ausgeführt werden:

Siehe https://medium.com/lagierandlagier/nextjs-webassembly-and-web-workers-a5f7c19d4fd0

Troubleshooting

Wenn zu wenig "Handles" für inotify-Überwachung durch den "Kompilierer" webpack oder die Testengine "Jest" zur Verfügung stehen, muss man Linux auf die Sprünge helfen:[3]

Man füge mit Root-Rechten folgende Zeile an die /etc/sysctl.conf:

 fs.inotify.max_user_watches=524288

Neuladen durch

 sudo sysctl -p