web-dev-qa-db-ja.com

TypeScriptとwebpackでWebワーカーを作成する方法

Web Workerを使用しようとすると、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宣言が怒鳴らないという問題があります。私の調査によると、別の標準ライブラリを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'._

だから私の質問は次のとおりです。ウェブワーカーがlib.webworker.d.ts定義を使用し、他のすべてが通常の定義に従うように指定するにはどうすればよいですか。

26
Rasmus Hansen

tsconfig.jsonファイルで、compilerOptionsでこれを設定します。

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

WebワーカーはDOM、windowdocumentおよびparentオブジェクトにアクセスできません(ここでサポートされているオブジェクトの完全なリスト: Web Workersが使用できる関数とクラス =); TypeScriptのdom libは互換性がなく、lib.webworker.d.tsで定義されているいくつかの要素を再定義します

17
batressc

Batresscの答えを使用して、私は実際にメッセージをやり取りすることに成功しました。

Libsでの彼の答えに加えて、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もあり、これに対してwebpackを設定する方法を示します。

19
Rasmus Hansen

rasmus-hansenのソリューションでは、基本形式では、ワーカーがモジュール自体をインポートすることはできません。さらに掘り下げた後、 https://github.com/Qwaz/webworker-with-TypeScript の例がそうであることがわかりました。 worker-loaderでバージョンをテストし、worker.tsentry.tsの両方でインポートできるよりも簡単なモジュールを簡単に追加できました。

2
lutzky