TypeScript 模块导入机制详解:ES6、CommonJS 与 --esModuleInterop
本文深入解析 TypeScript 中的模块导入机制,对比 ES6 模块与 CommonJS 规范的差异。重点介绍 TypeScript 2.7 引入的 --esModuleInterop 选项如何解决 CommonJS/AMD 模块导入时的调用与实例化限制,并阐明导入语句在编译后对类型信息与运行时依赖的处理逻辑。
TypeScript 模块导入机制详解:ES6、CommonJS 与 --esModuleInterop
前言
模块在独立的作用域内执行,而非全局作用域。因此,模块内部定义的变量、函数或类在外部不可见,除非通过 export 明确导出。反之,若需使用其他模块导出的内容,必须通过 import 语句导入。
模块具有自声明特性。在 TypeScript 中,文件间模块关系的建立依赖于文件级别的 import 和 export 声明。
下面话不多说了,来一起看看详细的介绍吧
ES6 模块导入的限制
ES6 模块导入的限制
我们先来看一个具体的例子:
在 Node 项目里,使用 CommonJS 规范引入一个模块:
const koa = require('koa')
改写为 TypeScript(1.5+ 版本)时,通常有两种方式:
使用 ES6 模块导入方式:
// allowSyntheticDefaultImports: false
import * as koa from 'koa'
使用 TypeScript 模块导入语法:
import koa = require('koa')
两者大部分是等价的,但 ES6 规范对 import * as 创建出的模块对象有一点限制。
根据该规范,该模块对象不可被调用,也不可被实例化,它只具有属性。
因此,如果你想调用该对象,或者使用 new 方法,在 allowSyntheticDefaultImports: false 的配置下,应该使用例子中的第二种方式。
2.7 版本对 CommonJs/AMD/UMD 模块导入的增强
2.7 版本对 CommonJs/AMD/UMD 模块导入的增强
在之前的版本,TypeScript 对 CommonJs/AMD/UMD 模块的处理方式与 ES6 模块相同,这会导致一些问题:
- 如前文所提到的,当导入一个 CommonJs/AMD/UMD 模块时,TypeScript 视 import * as koa from 'koa' 与 const koa = require('koa') 等价,但使用 import * as 创建的模块对象实际上不可被调用以及被实例化。
- 类似的,当导入一个 CommonJs/AMD/UMD 模块时,TypeScript 视 import foo from 'foo' 与 const koa = require('koa').default 等价,但在大部分 CommonJs/AMD/UMD 模块里,它们并没有默认导出。
在 2.7 的版本里,TypeScript 提供了一个新选项 --esModuleInterop,旨在解决上述问题, 当使用该选项,且模块为 CommonJs/AMD/UMD 时,它会导入一个可调用或是可实例化的模块,同时它规定该模块必须作为默认导入:
import koa from 'koa'
const app = new koa()
模块导入仅仅是一些声明类型
模块导入仅仅是一些声明类型
在以非相对路径导入一个模块时,你可能会看到 Could not find a declaration file for module 'someModule' 的错误, 此时你可以安装对应模块的声明文件或者写一个包含 declare module 'someModule' 的声明文件。 实际上,当我们导入一个模块时:
import koa from 'koa'
// import koa = require('koa')
它所做的事情只有两个:
- 导入模块的所有类型信息;
- 确定运行时的依赖关系。
当你加载此模块,但并没有使用,或仅当作类型来使用时,编译后,此模块将会被移除。
当不使用时;
import koa from 'koa'
编译后:
仅当做类型使用时:
import koa from 'koa'
let k: koa
编译后:
var k
做为值使用时,编译后,此模块将会被保留:
import koa from 'koa'
const app = new koa()
编译后(假设使用 commonjs):
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var koa_1 = __importDefault(require("koa"));
var k = new koa_1.default();
注: __importDefault 为使用 --esModuleInterop 选项时产生的方法。
参考
http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html https://stackoverflow.com/questions/35706164/typescript-import-as-vs-import-require?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa https://basarat.gitbooks.io/typescript/content/docs/project/external-modules.html
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对本站的支持。
JavaScript异步发送HTTP请求时怎么优雅地处理错误
2026-11-05 17:10:44
5款主流JS在线运行工具对比:CodePen、JSFiddle与StackBlitz怎么选
2026-11-05 17:04:04
JavaScript入门书籍避坑:这些书不适合初学者
2026-11-05 16:31:15
JS使用Math.round实现保留两位小数的原理与代码
2026-11-05 15:35:55
JavaScript 原生 Date 对象怎么实现日期加减
2026-11-05 14:30:00








