TypeScript 中 module 与 moduleResolution 的关系
解释为什么 module 与 moduleResolution 总是一起出现,但一个主要管输出模块格式,另一个主要管模块解析规则。
#tech / dev
#resource / typescript
#type / synthesis
#status / growing
[!info] related notes
TypeScript 中 module 与 moduleResolution 的关系
范围
这篇笔记专门解决一个常见混淆:为什么 module 和 moduleResolution 总一起改,但它们并不是同一个选项。
为什么要放在一起理解
它们都和“模块”有关,所以最容易被误解成:
- 一个控制 ESM / CJS
- 一个也控制 ESM / CJS
其实更准确的理解是:
module更偏“输出成什么”moduleResolution更偏“怎么找模块”
依赖路径 / 调用链 / 演进链
module
决定最终 JavaScript 更接近:
import/export- 还是
require/module.exports
moduleResolution
决定看到:
import { foo } from "./foo";
时,TypeScript 按哪套规则去解析。
它们为什么又不能完全分开
在 node16 / nodenext 模式下,最终输出到底会是 import 还是 require,会进一步影响 TypeScript 该用哪一套 Node 条件去解析 package exports。
因此两者虽然分工不同,但会互相耦合。
对比与易混淆点
典型组合
- Node 项目:
module: "nodenext"moduleResolution: "nodenext"
- bundler 项目:
module: "esnext"moduleResolution: "bundler"
典型误配
module: "esnext"+moduleResolution: "node16"
TypeScript 5.2 之后对此类不匹配配置更严格,很多情况下会直接报配置错误。