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",], コンパイルエラー
}
}