[解決済み】tsconfigファイルにおけるesModuleInteropの理解
質問
ある人を調べていたら
.tsconfig
というファイルを見つけ、そこで
--esModuleInterop
これは彼の
.tsconfig
ファイル
{
"compilerOptions": {
"moduleResolution": "node",
"target": "es6",
"module": "commonjs",
"lib": ["esnext"],
"strict": true,
"sourceMap": true,
"declaration": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"declarationDir": "./dist",
"outDir": "./dist",
"typeRoots": ["node_modules/@types"]
},
"include": ["src/**/*.ts"],
"exclude": ["node_modues"]
}
ここで、私の一番の疑問は
"esModuleInterop": true,
と
"allowSyntheticDefaultImports": true,
. これらは、ある種の
"module": "commonjs",
. どなたか、できるだけ人間の言葉で説明していただけませんか?
の公式ドキュメントは
allowSyntheticDefaultImports
の状態です。
デフォルトエクスポートがないモジュールからのデフォルトインポートを許可します。これは はコードエミットに影響を与えず、タイプチェックにのみ影響します。
どういう意味ですか?エクスポートデフォルトがない場合、インポートデフォルトの唯一の使用例は、何かを初期化することだと思うのですが?シングルトンとか?
次の質問と回答も同様に意味をなさない。 フラグではなく、tsconfigで--esModuleInteropを使用する方法はありますか?
そして
--esModuleInterop
コンパイラのページでの定義
実行時のバベルのために __importStar と __importDefault ヘルパーを出力する。 エコシステムの互換性のために --allowSyntheticDefaultImports を有効にしてください。 タイプシステムの互換性。
また、私には理解するのが難しいようです。
どのように解決するのですか?
問題提起
ES6モジュールのコードベースにCommonJSモジュールをインポートしたい場合に問題が発生する。
これらのフラグが付く前は、CommonJSモジュールをインポートする際には、星印(
* as something
) をインポートします。
// node_modules/moment/index.js
exports = moment
// index.ts file in our app
import * as moment from 'moment'
moment(); // not compliant with es6 module spec
// transpiled js (simplified):
const moment = require("moment");
moment();
を見ることができます。
*
とはどういうわけか等価であった。
exports
変数を使用します。これは問題なく動作しましたが、es6モジュールの仕様に準拠していませんでした。specでは、star importのnamespaceレコード(
moment
は、プレーンなオブジェクトのみで、呼び出し可能なものではありません (
moment()
は不可)。
解決方法
フラグ付き
esModuleInterop
に準拠した CommonJS モジュールをインポートすることができます。
es6
モジュール仕様です。これで、インポートコードは次のようになります。
// index.ts file in our app
import moment from 'moment'
moment(); // compliant with es6 module spec
// transpiled js with esModuleInterop (simplified):
const moment = __importDefault(require('moment'));
moment.default();
これは、es6 のモジュール仕様で完全に有効で、なぜなら
moment
は、star import の namespace ではなく、default import です。
しかし、どのように動作するのでしょうか?見ての通り、デフォルトのインポートを行ったので、その際に
default
プロパティに
moment
オブジェクトを作成します。しかし、私たちは
default
プロパティは
exports
オブジェクトを作成します。キーは
__importDefault
関数があります。これは、モジュール(
exports
) を
default
プロパティを使用します。
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
ご覧の通り、es6のモジュールをそのままインポートしていますが、CommonJSのモジュールはオブジェクトにラップして
default
キーが必要です。これにより、CommonJSのモジュールにデフォルトでインポートすることが可能になります。
__importStar
は同じような仕事をします。つまり、そのままの esModules を返しますが、CommonJS モジュールを
default
プロパティを使用します。
// index.ts file in our app
import * as moment from 'moment'
// transpiled js with esModuleInterop (simplified):
const moment = __importStar(require("moment"));
// note that "moment" is now uncallable - ts will report error!
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;
};
合成輸入品
そして、どうでしょう
allowSyntheticDefaultImports
- 何のためにあるのでしょうか?これで、ドキュメントが明確になったはずです。
Allow default imports from modules with no default export. This does not affect code emit, just typechecking.
で
moment
というのも、このフラグは
esModuleInterop
をオンにしています。ですから
allowSyntheticDefaultImports
は、デフォルトのエクスポートを持たないサードパーティモジュールからデフォルトをインポートしたい場合、エラーを報告しません。
関連
-
[解決済み] esModuleInterop が true の場合、明示的に allowSyntheticDefaultImports を使用して TypeScript transpilation を構成する必要がありますか?
-
[解決済み] タイプスクリプトのコンパイルで「tsc コマンドが見つかりません。
-
[解決済み] error TS2339: Property 'x' does not exist on type 'Y'.
-
ts 学習日記1 AssertionError [ERR_ASSERTION]: タスク関数を指定する必要があります
-
[解決済み] Webpack with typescriptでTypeScript emitted no outputエラーが発生する。
-
[解決済み] eslintをtypescriptで使用する - モジュールへのパスを解決できない
-
[解決済み] TSがモジュールを見つけ出せない
-
[解決済み] Jestで関数をモックする方法
-
[解決済み] モジュール 'module-name' の宣言ファイルが見つかりませんでした。'/path/to/module-name.js' は暗黙のうちに 'any' 型を持っています。
-
[解決済み】tsconfig.jsonファイルを生成するにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Typescript: スプレッド型はオブジェクト型からしか作成できない
-
[解決済み】ブロックスコープ付き変数の再宣言ができない(typescript)
-
[解決済み] React JSX ファイルでエラー "Cannot read property 'createElement' of undefined" が発生する。
-
[解決済み] error TS2339: Property 'x' does not exist on type 'Y'.
-
[解決済み] TypeScriptで文字列を数値に変換する方法とは?
-
[解決済み] TypeScriptでオブジェクトに動的にプロパティを割り当てるには?
-
[解決済み] String型とstring型の違いは何ですか?
-
[解決済み] TypeScriptのクラス型チェック
-
[解決済み】TypeScriptの関数のオーバーローディング
-
[解決済み】引数として渡されたTypeScriptオブジェクトにデフォルト値を設定する