TypeScript Module(ES2015) WebWorker 覚え書き

投稿日:

TypeScriptでES Moduleを使用するときの覚え書き。TypeScriptでそのままimport文を変換せずにそのまま出力、モジュールから別のモジュールを参照。 WebWorkerのpostMessageコンパイルエラー対策。調べるのに少し手間取ったのでメモ書き 。

import文をそのまま出力

次のようなimportをtsファイルに記述してデフォルト設定でコンパイルすると

コンパイル前.tsimport * as mymod from "./mymod.js"
mymod.foo();
コンパイル結果.js"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
var mymod = __importStar(require("./mymod.js"));
mymod.foo();

このようになります。ES2015以降に限定するプログラムの場合など、変換せずにimportをそのまま出力するには、tsconfigの module を”es2015″に変更します。

{
  "compilerOptions": {
    /* Basic Options */
    // "incremental": true,                   /* Enable incremental compilation */
    "target": "ES2015",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
    "module": "es2015",                       /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    //以下省略
  },
}

これでimportがそのまま出力されます。

コンパイル結果.jsimport * as mymod from "./mymod.js";
mymod.foo();

モジュールの共有

異なるモジュールが同一のモジュールmod0を共有したい場合

mod1.tsimport * as mod0 from "./mod0.js";
mod0.foo();
mod2.tsimport * as mod0 from "./mod0.js";
mod0.foo();

こうすると、それぞれのmod0は別々に (別々のメモリに) 構築されたものになります(違っていたらごめんなさい) 。 処理の共有であってメモリ(オブジェクト)の共有ではありません。そうではなく、mod0をオブジェクトとして共有したい場合、mod0を1回だけimportして、それをオブジェクトとしてmod1にmod2に渡すことで実現できます。

import * as mod0 from "./mod0.js";
import * as mod1 from "./mod1.js";
import * as mod2 from "./mod2.js";

// 同一モジュールmod0を共有
mod1.foo(mod0);
mod2.foo(mod0);
mod1.js mod2.jsexport function foo(mod0) {
    //mod0利用可能
} 

JavaScriptではこれで問題ないのですが、TypeScriptではmod0の型を指定しないとコンパイルエラーになります。なので、型の定義を行います。

mod1.ts mod2.tsexport function foo(mod0 : typeof import("./mod0.js")){
    //mod0利用可能
}

モジュール内のクラス参照とか

let foo : import("./mod0.js").ClassName;

importを使用していますが型情報の参照のみなので、JSファイルにimport関連のコードは出力されません。

WebWorkerでpostMessgae

WebWorkerでpostMessageを使用してコンパイルすると DOMのpostMessage と認識され引数エラーになります。同じ名前ですがDOMとWebWorkerでは異なる関数なので、TypeScriptにどちらの関数か指定する必要があります。

関数を再定義してエラーチェックを無効にする方法


declare function postMessage(message: any, trans? : any) : void;

tsconfigの “compilerOptions” > “lib” に”webworker”を追加する方法。
ただし”dom”と同時に使えないため、dom系処理とは別のプロジェクトとtsconfig.jsonを作成。 こちらが正式な対応 (たぶん)。

{
    "compilerOptions": {
      "target": "es5", 
      "lib": ["es5", "webworker",],  
      //"lib": ["es5", "dom", "webworker",], コンパイルエラー
    }
}

コメントを残す

メールアドレスが公開されることはありません。

認証:数字を入力してください(必須) * Time limit is exhausted. Please reload CAPTCHA.