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?
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
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.
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
.