Подтвердить что ты не робот

Как сделать веб-работников с помощью TypeScript и webpack

У меня возникли проблемы с правильной компиляцией моего typescript, когда я пытаюсь использовать веб-работников.

У меня есть рабочий, определенный следующим образом:

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

В другой части моего приложения я использую загрузчик рабочего стола webpack для загрузки моего рабочего следующим образом: let Worker = require('worker!../../../workers/uploader/main');

У меня, однако, есть некоторые проблемы с тем, что объявления typescript не кричат ​​на меня, когда приложение должно быть переписано. Согласно моим исследованиям, я должен добавить еще один стандартный lib в мой файл tsconfig, чтобы выявить глобальные переменные, к которым рабочий должен получить доступ. Они я так сказал:

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

Теперь, когда я запускаю webpack, чтобы построить все, я получаю кучу таких ошибок: 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'.

Итак, мой вопрос: как я могу указать, что webworker использует определения lib.webworker.d.ts, а все остальное следует за нормальными определениями?

4b9b3361

Ответ 1

В вашем tsconfig.json файле, в compilerOptions установите это:

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

Веб-работники не могут получить доступ к объектам DOM, window, document и parent (полный список поддерживаемых объектов здесь: Доступны функции и классы для веб-работников); dom lib из TypeScript несовместим и переопределяет некоторые элементы, которые определены в lib.webworker.d.ts

Ответ 2

Используя ответ batressc, мне удалось на самом деле заставить передачу сообщений туда-сюда работать, довольно приятным образом.

В дополнение к его ответу с помощью библиотек, код Typescript также нуждается в некоторых толчках, чтобы начать работать.

Сначала создайте файл, чтобы загрузчик файлов взаимодействовал с вами при импорте. У меня есть файл с именем file-loader.d.ts со следующим содержимым:

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

Далее, в ваш main.ts импортируйте работника с помощью загрузчика файлов:

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

Этот workerPath может затем использоваться для создания фактического работника:

const worker = new Worker(workerPath);

Затем создайте фактический рабочий файл test.worker.ts со следующим содержимым:

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

Затем вы можете отправлять сообщения туда и обратно в файле main.ts:

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

Я собрал все в репозитории github, если кому-то нужна полная перспектива, чтобы все заработало: https://github.com/zlepper/typescript-webworker

Этот репозиторий также имеет webpack.config.js, чтобы показать, как веб-пакет может быть настроен для этого.

Ответ 3

Решение rasmus-hansen в своей базовой форме не позволяет рабочим самостоятельно импортировать модули. После некоторого дополнительного поиска я обнаружил, что пример приведен в https://github.com/Qwaz/webworker-with-typescript. Я протестировал версию в worker-loader и смог тривиально добавить простой модуль, который можно импортировать как worker.ts и entry.ts.