模块导出与导入

导出

1
2
3
4
5
6
7
let a1 = 100
let a2 = 200
function hello() {
console.log('小康你好')
}

export { a1, a2, hello }

没有默认导出

如果一个模块没有默认导出

1
2
3
4
// m1.ts
export let obj = {
x: 1
}

则在引入该模块的时候,需要使用下列一些方式来导入

1
2
3
4
5
6
7
8
9
10
// main.ts
// error: 提示 m1 模块没有默认导出
import v from './m1'

// 可以简单的使用如下方式
import {obj} from './m1'
console.log(obj.x)
// or
import * as m1 from './m1'
console.log(m1.obj.x)

导入

1
2
3
4
5
import { a1, hello } from './a'

console.log(a1)

hello()

模块编译

TypeScript 编译器也能够根据相应的编译参数,把代码编译成指定的模块系统使用的代码

module 选项

TypeScript 编译选项中,module 选项是用来指定生成哪个模块系统的代码,可设置的值有:"none""commonjs""amd""udm""es6"/"es2015/esnext""System"

  • target=="es3" or "es5":默认使用 commonjs
  • 其它情况,默认 es6

加载非 TS 文件

有的时候,我们需要引入一些 js 的模块,比如导入一些第三方的使用 js 而非 ts 编写的模块,默认情况下 tsc 是不对非 ts 模块文件进行处理的

我们可以通过 allowJs 选项开启该特性

1
2
3
4
// m1.js
export default 100;
// main.ts
import m1 from './m1.js'

ESM 模块中的默认值问题

如果在js文件中导出的模块没有默认导出,那么在ts中加载需要在编译配置中打开allowSyntheticDefaultImports选项。

虽然可以编译通过,但生成的文件会默认调用default属性,因此打印出的结果是undefined,因此为了处理默认值问题,还需要打开esModuleInterop选项。

因此,如果处理非默认导出模块需要开启三个选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"compilerOptions": {
// ...

// 1. 处理js文件
"allowJs": true,

// 2. 允许从没有设置默认导出的模块中默认导入
"allowSyntheticDefaultImports": true,

// 3. 则在编译的同时生成一个 `__importDefault` 函数,用来处理具体的 `default` 默认导出
"esModuleInterop": false
},
"include": ["./src/**/*"]
}

注意:以上设置只能当 module 不为 es6+ 的情况下有效

以模块的方式加载 JSON 格式的文件

TypeScript 2.9+ 版本添加了一个新的编译选项:resolveJsonModule,它允许我们把一个 JSON 文件作为模块进行加载

resolveJsonModule

设置为:true ,可以把 json 文件作为一个模块进行解析

data.json

1
2
3
4
5
{
"name": "小康",
"age": 18,
"gender": "男"
}

ts文件

1
2
import * as userData from './data.json';
console.log(userData.name);

命名空间

TS 中,exportimport 称为 外部模块,TS 中还支持一种内部模块namespace,它的主要作用只是单纯的在文件内部(模块内容)隔离作用域

1
2
3
4
5
6
7
8
9
10
11
namespace k1 {
let a = 10;
export var obj = {
a
}
}

namespace k2 {
let a = 20;
console.log(k1.obj);
}

自用配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"compilerOptions": {
"outDir": "./dist",
"target": "es5",
"watch": true,
// 严格空检查
"strictNullChecks": true,
// 指定生成哪个模块系统的代码
"module": "CommonJS",
// 处理js文件
"allowJs": true,
// 允许从没有设置默认导出的模块中默认导入
"allowSyntheticDefaultImports": true,
// 则在编译的同时生成一个 `__importDefault` 函数,用来处理具体的 `default` 默认导出
"esModuleInterop": true,
// 加载JSON文件
"resolveJsonModule": true,
// 启用装饰器
"experimentalDecorators": true
},
"include": ["./src/**/*"]
}