在TS中使用模块化
配置名称 | 含义 |
---|---|
module | 设置编译结果中使用的模块化标准 |
moduleResolution | 设置解析模块的模式 |
noImplicitUseStrict | 编译结果中不包含”use strict” |
removeComents | 编译结果移除注释 |
noEmitOnError | 错误时不生成编译结果(为了防止有时错误了也可以编译) |
esModuleInterop | 启用es模块化交互非es模块导出 |
前端领域中的模块化标准:ES6,commonjs、amd、umd、system、esnext
在TS中如何书写模块化语句
ES6出来之后,TS就支持ES6了
所以,在TS中,导入和导出模块,统一使用ES6的模块化标准
写了一个不存在的东西时,ts会去模块中寻找有没有同名的,有的话就会提示你是否要导入(必须是普通导出)
导入的时候千万不要加上.ts!!因为编译结果里没有.ts都是.js!!
编译结果中的模块化是什么样的
commonjs?es6?都行,可以配置的。在配置文件的 compilerOptions.module 中
如果编译结果的模块化是es6标准
则几乎无差异(换行删除了),默认连注释也会变异到结果中,
“removeComments”: true,//移除注释
如果编译结果的模块化是commonjs标准
- 默认加入了”use strict”, 其实没必要,因为ts比这个要严格,开启
- “noImplicitUseStrict”: true,//即可在编译结果中删除use strict
- 注释默认也会编译进结果
- 导出的声明会变成exports的属性,默认导出会变成exports的default属性
导出:
导入:
Object.defineProperty(exports, “__esModule”, { value:true });
相当于是:
exports.__esModule = true;
解决默认导入的错误
这是为什么?
//ts源代码
import fs from 'fs';
fs.readFileSync("./myModule.ts");
//编译结果
const fs_1 = require("fs");
fs_1.default.readFileSync("./myModule.ts");
究其根源,fs模块不是用ts写的,而且它用的是 module.exports = {} 即commonjs标准导出的,导入没有使用解构对象的语法,把它当作了默认导出,而commonjs没默认导出,所以才会提示有问题,虽然编译可以通过
怎么解决?
- 写成解构对象呗: import { readFileSync } from ‘fs’;
- 利用 : **import as fs from ‘fs’;**
- 如果非要写import fs from ‘fs’; 那行吧,还有办法,进行配置
- esModuleInterop: 启用es模块化交互非es模块导出
增加了一些辅助函数,😓
如何在TS中书写commonjs模块化导入导出代码
其实光是普通的写,当然可以写,没问题,但是呢,你无法获取类型检查了,得到的是any
但ts的要求是es6,如果有一天,一定要在ts中书写commonjs模块化代码,怎么办?
按下述这样做:
//导入
import myModule = require('./myModule');
//导出
export = xxxx;
模块解析
在TS中,有两种模块解析策略:
- classic:经典,在es6之前就出来了,已经过时了
- node:node解析策略,常用
- 与node本身的解析策略的唯一不同是,是将js替换成ts!当然,编译之后,找的还是js!
为了避免出错,固定死为node解析策略,配置 “moduleResolution”: “node”,
对于node解析策略:
- 相对路径:require(‘./xxx’);
- 先找当前目录下
- 没有找到,就再找package.json中配置的main,把其值当作文件夹名,找其下的index.ts
- 非相对路径:require(‘xxx’);
- 先找当前目录下的node_modules,没有就一直往上级目录的node_modules里找