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 模块导入的增强
在之前的版本, 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
来源: https://juejin.im/post/5a2cce856fb9a0450e760ca3