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 === |
| | | |