web-dev-qa-db-fra.com

Comment faire des travailleurs Web avec TypeScript et webpack

J'ai des problèmes avec la compilation correcte de mon TypeScript lorsque j'essaie d'utiliser des travailleurs Web.

J'ai un travailleur défini comme ceci:

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

Dans une autre partie de mon application, j'utilise le chargeur de travail Webpack pour charger mon travailleur comme ceci: let Worker = require('worker!../../../workers/uploader/main');

J'ai cependant quelques problèmes avec le fait que les déclarations TypeScript ne me crient pas dessus quand l'application doit être transposée. Selon mes recherches, je dois ajouter une autre bibliothèque standard à mon fichier tsconfig pour exposer les variables globales auxquelles le travailleur doit accéder. Ceux que j'ai spécifiés ainsi:

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

Maintenant, quand j'exécute webpack pour le faire tout construire, je reçois un tas d'erreurs comme celles-ci: 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'.

Ma question est donc la suivante: comment spécifier si le webworker utilise les définitions lib.webworker.d.ts et tout le reste suit les définitions normales?

26
Rasmus Hansen

Dans votre tsconfig.json fichier, dans compilerOptions définissez ceci:

{
    "compilerOptions": {
        "target": "es5",
        //this config for target "es5"
        "lib": ["webworker", "es5", "scripthost"]
        //uncomment this for target "es6"
        //"lib": ["webworker", "es6", "scripthost"]
    }
}

Les travailleurs Web ne peuvent pas accéder aux objets DOM, window, document et parent (liste complète des objets pris en charge ici: Fonctions et classes disponibles pour les travailleurs Web =); la librairie dom de TypeScript n'est pas compatible et redéfinit certains éléments définis dans lib.webworker.d.ts

17
batressc

En utilisant la réponse de batressc, j'ai réussi à faire passer les messages dans les deux sens, d'une manière plutôt agréable.

Ajoutant à sa réponse avec les bibliothèques, le code TypeScript a également besoin de quelques coups de pouce pour fonctionner.

Créez d'abord un fichier pour que le chargeur de fichiers coopère avec vous lors de l'importation. J'ai un fichier nommé file-loader.d.ts avec le contenu suivant:

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

Ensuite, dans votre main.ts importer le travailleur à l'aide du chargeur de fichiers:

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

Ce workerPath peut ensuite être utilisé pour créer le travailleur réel:

const worker = new Worker(workerPath);

Ensuite, créez le fichier de travail réel, test.worker.ts, avec le contenu suivant:

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

Vous pouvez ensuite envoyer des messages dans les deux sens dans le main.ts fichier:

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

J'ai tout rassemblé dans un référentiel github, si quelqu'un a besoin de la perspective complète pour que tout fonctionne: https://github.com/zlepper/TypeScript-webworker

Ce référentiel a également un webpack.config.js pour montrer comment le webpack pourrait être configuré pour cela.

19
Rasmus Hansen

la solution de rasmus-hansen ne permet pas, dans sa forme de base, aux travailleurs d'importer eux-mêmes des modules. Après avoir creusé un peu plus, j'ai trouvé que l'exemple de https://github.com/Qwaz/webworker-with-TypeScript le fait. J'ai testé la version dans worker-loader, et a été en mesure d'ajouter trivialement un module simple qui peut être importé par les deux worker.ts et entry.ts.

2
lutzky