| Zeile 160: |
Zeile 160: |
| | 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. |
| | + | |
| | + | Daher nutzt man 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"; |
| | + | 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({org:event, orgData: event.data, now:new Date()}) |
| | + | }); |
| | + | </pre> |
| | + | |
| | + | |
| | + | === Aufruf 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> |
| | + | |
| | === Troubleshooting === | | === Troubleshooting === |
| | | | |