TypeScript 中的 moduleResolution
说明 moduleResolution 如何决定 TypeScript 把 import 字符串解析到磁盘文件、node_modules 和 package.json exports/imports 的规则。
#tech / dev
#resource / typescript
#type / concept
#status / growing
[!info] related notes
- 所属 MOC: TypeScript MOC
- 配置入口: tsconfig 使用详解
- 并列概念: TypeScript 中的 module, TypeScript 中的 customConditions, TypeScript 中的 resolvePackageJsonExports, TypeScript 中的 resolvePackageJsonImports, TypeScript 中的 moduleSuffixes, TypeScript 中的 rewriteRelativeImportExtensions, TypeScript 中的 allowImportingTsExtensions
- 关系笔记: TypeScript 中 module 与 moduleResolution 的关系, Node、bundler 与 TypeScript 模块解析的关系
TypeScript 中的 moduleResolution
一句话定义
moduleResolution 决定 TypeScript 如何把 import / export / require 里的字符串解析到真实文件和类型定义。
核心机制 / 工作原理
它回答的是:
import "./foo"或import "pkg"到底应该按哪套规则去磁盘、node_modules、package.json exports/imports里找目标。
这包括:
- 相对路径查找
node_modules查找package.json exportspackage.json imports- 是否允许省略扩展名
在现代条件导出场景里,还可能进一步细分到:
- TypeScript 中的 customConditions
- TypeScript 中的 resolvePackageJsonExports
- TypeScript 中的 resolvePackageJsonImports
在多平台文件后缀或较新的相对导入扩展名场景里,还可能继续细分到:
- TypeScript 中的 moduleSuffixes
- TypeScript 中的 rewriteRelativeImportExtensions
- TypeScript 中的 allowImportingTsExtensions
常见模式
node10node16nodenextbundler
现代项目里最常讨论的是:
nodenextbundler
最小例子 / 最小场景
import { foo } from "./foo";
import { bar } from "some-package";
TypeScript 需要决定:
./foo是否能省略扩展名some-package是否该读exports- 当前导入应走
import条件还是require条件
这些都属于 moduleResolution 的职责。
边界与易混淆点
moduleResolution 不等于输出模块格式
它管的是“怎么找”,不是“输出成什么”。
它应该匹配真实 runtime 或 bundler
官方文档明确建议:moduleResolution 应该匹配你的目标运行环境或打包器,而不是随便选一个“能过类型检查”的值。
参考信息
- TSConfig
moduleResolution: https://www.typescriptlang.org/tsconfig/moduleResolution.html - Modules Reference: https://www.typescriptlang.org/docs/handbook/modules/reference