ウェブサイト検索

TypeScriptに私のファイルをモジュールとして扱わせるにはどうすればいいですか?


https://www.typescriptlang.org/docs/handbook/modules.html より:

TypeScriptでは、ECMAScript 2015と同様に、トップレベルのimportまたはexportを含むファイルはすべてモジュールと見なされます。逆に、トップレベルのimportやexport宣言を含まないファイルは、その内容がグローバルスコープ(したがってモジュールからも)で利用可能なスクリプトとして扱われます。

この行動は驚くべきで望ましくありません。どうすれば防ぐことができますか?

副作用のために書かれた TypeScript モジュール、lib.ts を考えてみましょう。

var myglobal = 3;
console.log(`lib.ts: myglobal = ${myglobal}`);

次に、lib.tsを副作用のためにインポートするファイルであるmain.tsを考えてみましょう:

import './lib.js';
console.log(`main.ts: myglobal = ${myglobal}`);

完全性のために、tsconfig.jsonを提供します:

{
  "compilerOptions": {
    "lib": ["ES2015", "DOM"],
    "module": "ES2015",
    "strict": true
  },
  "files": ["main.ts", "lib.ts"]
}

これはコンパイルに失敗するはずのように見えますが、tscは成功してしまい、私は非常に残念に思いました。その後、私は結果をrollup.jsでバンドルします。

export default {
  input: "main.js",
  output: {
    file: "bundle.js",
    format: "module",
  },
};

結果として得られる出力は、Rollup と TypeScript が lib.ts 内の myglobal が main.ts から見えるかどうかについて明らかに意見が異なることを示しています。なぜなら、Rollup は myglobal が main 内で自由変数であることに気付き、lib 内で名前を変更すべきだと結論するからです。

var myglobal$1 = 3;
console.log("lib.ts: myglobal = " + myglobal$1);

console.log("main.ts: myglobal = " + myglobal);

それを実行すると、失敗します。

node bundle.js 
lib.ts: myglobal = 3
/redacted/bundle.js:4
console.log("main.ts: myglobal = " + myglobal);
                                     ^

ReferenceError: myglobal is not defined
    at Object. (/redacted/bundle.js:4:38)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47

TypeScriptではコンパイル時のエラーであるべきものが、現在は実行時エラーになっています。意図した通りにlib.jsをモジュールとして扱うように、TypeScriptをどのように設定すればよいですか?

(ES2015の仕様を調べても、「トップレベルのimportまたはexportを含む任意のファイルはモジュールと見なされる」という主張をサポートするものは見つかりませんでした。実際、ファイルがモジュールかどうかは、JavaScriptパーサのゴールシンボルに影響するため、解析が始まる前に決定されるようです。では、TypeScriptのドキュメントのこの部分は意味を成しているのでしょうか?)

回答 #1

ファイルがモジュールであるかどうかは、そのファイルがどのような文脈で読み込まれるかによりますが、TypeScript(TS)はそれを知る方法がないため、ファイルの内容に基づいた手がかりが必要です。インポートやエクスポートを行わないファイルは非常にまれであるため、import および export 宣言を使用して、ファイルがモジュールであるかどうかを推測します。

ファイルに export { } を追加すると、それをモジュールにすることができます。

回答 #2

'--isolatedModules' でコンパイルを試みると、TypeScript がモジュールとして認識しないファイルでは即座にエラーが発生します。また、いくつかの TypeScript 機能の使用も制限されます。

関連記事