目录
- 1,ts 中如何使用模块化
- 2,编译结果中的模块化
- 2.1,使用 node 模块的问题
- 3,模块解析的策略
一些用到的配置项:
配置名称 | 含义 | 常见取值 |
---|---|---|
module | 设置编译结果中,使用的模块化标准 | es6 ,commonjs |
moduleResolution | 设置解析模块的模式 | node |
alwaysStrict | 编译结果中不包含 "use strict" ,(旧版 ts 该配置项是 noImplicitUseStrict ) | true ,false |
removeComments | 编译结果中,移除注释 | true ,false |
noEmitOnError | 发生错误时,不生成编译结果 | true ,false |
esModuleInterop | 启用 es 模块化交互,但导出使用非 es 模块 | true ,false |
1,ts 中如何使用模块化
导入导出,统一使用 es6 模块化标准即可。
2,编译结果中的模块化
如果在 ts 中使用 es6 模块化标准,在编译为 js 时:
- 配置
module
为es6
时,结果无变化 - 配置
module
为commonjs
时,导出的声明会变成exports
的属性,默认导出会变成exports
的default
属性。
也可以用这一特性,来对比 es6 和 commonjs 的写法区别。
2.1,使用 node 模块的问题
import fs from "fs";
fs.readFileSync('./')
编译为 commonjs 后(node 使用的 commonjs )
const fs_1 = require("fs");
fs_1.default.readFileSync('./');
原因:node 模块不是 ts 写的,而且 fs
并不是默认导出。
另外,需要安装
@types/node
才有智能提示。
3种解决办法:
1,
import {readFileSync} from "fs";
readFileSync('./')
2,
import * as fs from "fs";
fs.readFileSync('./')
前2个编译为 commonjs 后:
const fs_1 = require("fs");
fs_1.readFileSync('./');
3,配置 esModuleInterop: true
,则可以直接 import fs from "fs";
这样使用了。
编译为 commonjs 后,可以看到 __importDefault
函数返回了一个对象,对象的 default
属性值是require("fs")
,所以 fs_1.default.readFileSync('./');
就可以正常使用了。
var __importDefault = (this && this.__importDefault) || function (mod) {return (mod && mod.__esModule) ? mod : { "default": mod };
};
const fs_1 = __importDefault(require("fs"));
fs_1.default.readFileSync('./');
console.log('1');
3,模块解析的策略
很早之前 ts 版本使用的是 classic 经典模式,在 es6 和 node 出来之后,大多都会使用 node 解析策略。
- 相对路径:
require('./xxx')
- 先找引入路径目录下,也就是当前目录;
- 再找引入路径目录下的
package.json
中的 main 字段; - 再找引入路径目录下的
index.ts
。
- 非相对路径:
require('xxx')
- 找的是
node_modules
目录下的模块。从当前目录逐层往上查找node_modules
目录,一直到项目根目录。
- 找的是
以上。