TypeScript moduleResolution 取值对比

33 阅读2分钟

在 TypeScript 中,moduleResolution 决定了 编译器如何查找模块文件路径(即当你 import "foo" 时,TypeScript 怎样找到 foo 对应的文件)。

这个选项在不同项目类型(Node、前端、monorepo)中影响很大。下面是详细对比:

一、可选取值一览(截至 TS 5.6)

取值适用环境简介
classic旧版 JS 项目旧的非 Node 模块解析方式(几乎不再推荐)
nodeNode.js (CommonJS 模块)模拟 Node.js 的 CommonJS 模块解析逻辑
node16Node.js (ESM 模块)支持 ES 模块、.mts/.ctspackage.json"exports"
nodenextNode.js (ESM + CommonJS 混合)推荐用于现代 Node 项目,兼容性最好
bundler前端打包器 (Vite、Webpack、esbuild)模拟打包器行为,忽略 Node exports 限制
classic老旧、浏览器直接运行脚本仅用于历史原因,不推荐使用

二、主要取值对比表

特性classicnodenode16nodenextbundler
支持 node_modules❌ 否✅ 是✅ 是✅ 是✅ 是
支持 "exports" 字段❌ 否❌ 否✅ 是✅ 是🚫 忽略 "exports" 限制(直接解析路径)
支持 .mts / .cts / .d.mts 等扩展名❌ 否❌ 否✅ 是✅ 是✅ 是
支持混合 ESM/CJS❌ 否⚠️ 有限⚠️ 分开(需匹配文件扩展)✅ 是✅ 是
支持前端别名路径(例如 #/*@/*❌ 否❌ 否⚠️ 需配置✅/⚠️✅ 最好支持
最推荐使用场景旧项目Node.js CJSNode.js ESMNode.js 通用前端项目(Vite/Webpack)

三、常见组合(tsconfig 示例)

a) 前端项目(Vite)

{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "bundler",
    "target": "ESNext"
  }
}

b) Node ESM 项目

{
  "compilerOptions": {
    "module": "NodeNext",
    "moduleResolution": "nodenext",
    "target": "ES2022"
  },
  "type": "module"
}

c) Node CJS 项目

{
  "compilerOptions": {
    "module": "CommonJS",
    "moduleResolution": "node",
    "target": "ES2019"
  }
}

四、总结一句话记忆

  • 🧓 classic:古董遗产,别碰。
  • ⚙️ node:老式 Node.js 项目。
  • 🪄 node16:Node.js 的官方 ESM 规则。
  • 🧬 nodenext:ESM + CJS 混合模式,Node 项目首选。
  • 🎨 bundler:为打包器而生,前端项目首选。

其他内容