Skip to content
On this page

11.esModuleInterop

esModuleInteropallowSyntheticDefaultImports两个选项都是 TypeScript 编译器选项,用于处理 ES6 模块和 CommonJS 模块之间的兼容性问题。它们的主要目的是让 TypeScript 更容易与使用不同模块系统的 JavaScript 代码库进行互操作,但它们的作用和影响有所不同。

相同点

  1. 模块兼容性

    • 这两个选项都旨在解决 TypeScript 中 ES6 模块与 CommonJS 模块的兼容性问题,使得开发者可以更方便地导入和使用现有的 JavaScript 库。
  2. 启用方式

    • 两个选项都可以单独启用,也可以一起启用。不过,如果启用了 esModuleInterop,通常不需要再单独启用 allowSyntheticDefaultImports,因为 esModuleInterop 已经包含了 allowSyntheticDefaultImports 的功能。

不同点

  1. 作用范围

    • allowSyntheticDefaultImports

      • 允许从没有默认导出的模块中导入默认导出。这意味着即使模块没有实际的 default 导出,TypeScript 也会假设它有一个,并允许 import 语句使用默认导入。
      • 主要作用是让 TypeScript 可以更方便地导入 CommonJS 模块,尤其是那些没有明确默认导出的模块。
    • esModuleInterop

      • 启用所有与模块互操作相关的功能,包括 allowSyntheticDefaultImports。它的作用不仅仅限于允许默认导入,还包括重新调整 TypeScript 对模块的导入和导出行为,使其更符合 ES6 规范。
      • 还会为所有 export = 的模块生成默认导出,确保这些模块在 TypeScript 中可以使用默认导入语法。
  2. 编译器行为

    • allowSyntheticDefaultImports

      • 只是一个语法上的调整,允许使用默认导入语法,但不改变编译后的输出。
    • esModuleInterop

      • 改变编译输出,使其与 ES6 模块的行为更加一致。启用这个选项后,TypeScript 编译器会在生成的 JavaScript 代码中添加额外的帮助代码,以模拟 ES6 的模块行为。

示例

假设我们有一个 CommonJS 模块 commonjs-module.js

JavaScript
// commonjs-module.js
module.exports = { foo: 'bar' };

1
2
3
  1. 只启用 allowSyntheticDefaultImports
json
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true
  }
}

1
2
3
4
5
6

在 TypeScript 中:

typescript
import commonjsModule from './commonjs-module';
console.log(commonjsModule.foo); // 'bar'

1
2
3

编译后:

javascript
const commonjs_module_1 = require('./commonjs-module');
console.log(commonjs_module_1.default.foo); // 这里会报错,因为 `commonjs-module.js` 没有 `default` 导出

1
2
3
  1. 启用 esModuleInterop(隐含包含 allowSyntheticDefaultImports):
json
{
  "compilerOptions": {
    "esModuleInterop": true
  }
}

1
2
3
4
5
6

在 TypeScript 中:

typescript
import commonjsModule from './commonjs-module';
console.log(commonjsModule.foo); // 'bar'

1
2
3

编译后:

javascript
const tslib_1 = require('tslib');
const commonjs_module_1 = tslib_1.__importDefault(require('./commonjs-module'));
console.log(commonjs_module_1.default.foo); // 正确,因为 `__importDefault` 函数创建了一个默认导出

1
2
3
4

总结

相同点

  • 都是用于处理 ES6 模块与 CommonJS 模块的兼容性问题。
  • 都能简化从没有默认导出的模块中导入默认导出的操作。

不同点

  • allowSyntheticDefaultImports 仅仅允许使用默认导入语法,但不改变编译输出。
  • esModuleInterop 不仅允许使用默认导入语法,还会调整编译输出,使其与 ES6 模块行为一致,并包含了 allowSyntheticDefaultImports 的功能。

在现代 TypeScript 项目中,通常推荐启用 esModuleInterop,以便更好地支持模块互操作,并使编译后的代码更符合 ES6 模块规范。

沪ICP备20006251号-1