Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make web workers with TypeScript and webpack

I'm having some issues with properly compiling my typescript when I attempt to use web workers with Webpack.

I have a worker defined like this:

onmessage = (event:MessageEvent) => {   var files:FileList = event.data;     for (var i = 0; i < files.length; i++) {         postMessage(files[i]);     } }; 

In another part of my application i'm using the webpack worker loader to load my worker like this: let Worker = require('worker!../../../workers/uploader/main');

I'm however having some issues with making the typescript declarations not yell at me when the application has to be transpiled. According to my research i have to add another standard lib to my tsconfig file to expose the global variables the worker need access to. These i have specified like so:

{      "compilerOptions": {           "lib": [                "webworker",                "es6",                "dom"           ]      } } 

Now, when i run webpack to have it build everything i get a bunch of errors like these: C:/Users/hanse/Documents/Frontend/node_modules/typescript/lib/lib.webworker.d.ts:1195:13 Subsequent variable declarations must have the same type. Variable 'navigator' must be of type 'Navigator', but here has type 'WorkerNavigator'.

So my question is: How do I specify so the webworker uses the lib.webworker.d.ts definitions and everything else follows the normal definitions?

like image 220
Rasmus Hansen Avatar asked Aug 02 '16 08:08

Rasmus Hansen


1 Answers

Using batressc' answer I have managed to actually get passing messages back and forth working, in a somewhat nice manner.

Adding to his answer with the libs, the Typescript code also needs some nudges to get working.

First, create a file to make the file-loader cooperate with you when importing. I have a file named file-loader.d.ts with the following contents:

declare module "file-loader?name=[name].js!*" {     const value: string;     export = value; } 

Next, in your main.ts import the worker using the fileloader:

import * as workerPath from "file-loader?name=[name].js!./test.worker"; 

This workerPath can then be used to create the actual worker:

const worker = new Worker(workerPath); 

Next, create the actual worker file, test.worker.ts, with the following content:

addEventListener('message', (message) => {     console.log('in webworker', message);     postMessage('this is the response ' + message.data); }); 

You can then send messages back and forth in the main.ts file:

worker.addEventListener('message', message => {     console.log(message); }); worker.postMessage('this is a test message to the worker'); 

I have gathered everything in a github repository, if someone needs to the full perspective to get everything working: https://github.com/zlepper/typescript-webworker

This repository also have a webpack.config.js to show how webpack could be configured for this.

like image 61
Rasmus Hansen Avatar answered Oct 06 '22 06:10

Rasmus Hansen