在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标准

  1. 默认加入了”use strict”, 其实没必要,因为ts比这个要严格,开启
    1. “noImplicitUseStrict”: true,//即可在编译结果中删除use strict
  2. 注释默认也会编译进结果
  3. 导出的声明会变成exports的属性,默认导出会变成exports的default属性

导出:
image.png
导入:
image.png
Object.defineProperty(exports, “__esModule”, { value:true });
相当于是:
exports.__esModule = true;

解决默认导入的错误

image.png这是为什么?

  1. //ts源代码
  2. import fs from 'fs';
  3. fs.readFileSync("./myModule.ts");
  4. //编译结果
  5. const fs_1 = require("fs");
  6. fs_1.default.readFileSync("./myModule.ts");

究其根源,fs模块不是用ts写的,而且它用的是 module.exports = {} 即commonjs标准导出的,导入没有使用解构对象的语法,把它当作了默认导出,而commonjs没默认导出,所以才会提示有问题,虽然编译可以通过

怎么解决?

  1. 写成解构对象呗: import { readFileSync } from ‘fs’;
  2. 利用 : **import as fs from ‘fs’;**

image.png

  1. 如果非要写import fs from ‘fs’; 那行吧,还有办法,进行配置
    1. esModuleInterop: 启用es模块化交互非es模块导出

image.png
增加了一些辅助函数,😓

如何在TS中书写commonjs模块化导入导出代码

其实光是普通的写,当然可以写,没问题,但是呢,你无法获取类型检查了,得到的是any
但ts的要求是es6,如果有一天,一定要在ts中书写commonjs模块化代码,怎么办?
按下述这样做:

  1. //导入
  2. import myModule = require('./myModule');
  3. //导出
  4. export = xxxx;

模块解析

模块解析:应该从什么位置寻找模块

在TS中,有两种模块解析策略:

  1. classic:经典,在es6之前就出来了,已经过时了
  2. node:node解析策略,常用
    1. 与node本身的解析策略的唯一不同是,是将js替换成ts!当然,编译之后,找的还是js!

为了避免出错,固定死为node解析策略,配置 “moduleResolution”: “node”,

对于node解析策略:

  1. 相对路径:require(‘./xxx’);
    1. 先找当前目录下
    2. 没有找到,就再找package.json中配置的main,把其值当作文件夹名,找其下的index.ts
  2. 非相对路径:require(‘xxx’);
    1. 先找当前目录下的node_modules,没有就一直往上级目录的node_modules里找