# 模块解析
在 TypeScript 中使用 import a from 'ModuleA' 或
import a from './ModuleA' 语法时,TypeScript 如何确定 ModuleA 的实际位置?编译器分析导入内容位置的过程就是本章讨论的模块解析 。
# 模块解析概述
TypeScript 存在两种典型的 模块解析 策略。
- Classic
- Node
# 关联导入和非关联导入
- 关联导入(relative import) 以
/,./,../.开头的导入,本地文件的导入 - 非关联导入(non-relative import) 模块名的方式导入,引用三方的模块导入,例如
import * as $ from "jquery",import { Component } from "@angular/core";,非关联导入具有如下特性- 可以通过
baseUrl配置改变 模块解析 规则 - 会解析 ambient module declarations
- 可以通过
# 模块解析策略
- moduleResolution 配置可以修改解析策略
- 未显示指定模块解析策略时根据配置的
module类型处理解析规则- commonjs 采用 node 解析
- amd, system, umd, es2015, esnext 采用 classic 模式解析
TIP
在开发 npm 包时,若定义模块为 es2015, esnext 的 esm 导出方式,则建议配置 moduleResolution 为 node, 采用类似 node 的方式处理模块解析
# Classic 策略
- 关联导入
- 先解析路径下的
.ts为后缀的文件 - 若无则查找
.d.ts文件
- 先解析路径下的
- 非关联导入
- 在当前目录查找
.ts为后缀的模块名文件 - 若无,则在当前目录查找
.d.ts结尾的模块名文件 - 若无则,则在上一级目录重复步骤 1,2
- 若无则重复步骤 3
- 在当前目录查找
若最后模块解析失败,ts 会抛出
error TS2307: Cannot find module xxx.的信息
# Node 策略
加载机制详见 node 模块加载机制 (opens new window)
重点如下:
- 相对路径
- node 会先加载不带任何后缀的文件作为 js 文件解析,随后按照
js,json,node的后缀加载文件 - 若文件无法查找到,按照同名文件夹会读取
package.jsonmain 字段,不存在会查找index文件按照js,json,node扩展顺序进行加载注意此处不会加载没有扩展名文件,若文件夹下 index 无扩展名会直接抛出错误
- node 会先加载不带任何后缀的文件作为 js 文件解析,随后按照
- 绝对路径
- 对于不包含路径的模块,会先去加载内部模块若失败,会根据
module.paths的一系列目录加载,回逐级向上查找node_modules目录寻找模块可以通过
NODE_PATH来增加解析路径。利用:分隔多个目录。windows 为;
- 对于不包含路径的模块,会先去加载内部模块若失败,会根据
TypeScript 的规则类似
- 相对路径查找
./moduleB- 在当前路径查找名为
moduleB.ts,moduleB.tsx,moduleB.d.ts的文件 - 在当前路径的
package.json查找 types 字段对应的文件位置 - 在当前路径
moduleB文件夹下查找index.ts,index.tsx,index.d.ts文件 - 若未找到退化到 node 的查找机制
- 在当前路径查找名为
- 绝对路径,查找
moduleB- 在
node_modules目录查找后缀为moduleB.ts,moduleB.tsx,moduleB.d.ts文件 - 在
node_modules/moduleB/package.jsontypes字段查找.ts,.tsx,.d.ts文件 - 在
node_modules/moduleB字段查找index.ts,index.tsx,index.d.ts文件 - 在
node_modules/@types/moduleB.d.ts字段查找index.ts,index.tsx,index.d.ts文件 - 在
node_modules/@types/moduleB字段查找index.ts,index.tsx,index.d.ts文件 - 重复 1-5 向上一层查找
node_modules目录
- 在
# 模块解析配置
除了上述默认查找规则,可以利用如下配置定义解析器查找机制。
baseUrl所有非相对路径模块导入会参考此地址导入。paths有时模块的位置上述查找无法生效,例如 jquery 的编译文件定义在node_modules/jquery/dist/jquery为了避免查找失败,通过此路径匹配注意
paths的值是相对于baseUrl而言的,所以需要设置baseUrl为.避免查找失败 也可利用此示例实现跨模块查找rootDirs实现编译时的动态载入,详见 rootDirs (opens new window)
# export type
详见 export type (opens new window)
# 知识点
- 解决什么问题
- 核心概念有哪些
- 导入定义
- 关联导入(relative import) 以
/,./,../.开头的导入 - 非关联导入(non-relative import)
- 关联导入(relative import) 以
- 导入定义
- 如何影响该特性
- 实际使用场景