2026 TypeScript compilerOptions.module 如何选择

背景

  • date: 2026-01-05; TypeScript latest: v5.9.3;
  • Node.js 支持 require(esm) 了, 库作者只用考虑 esm 了. 感谢 joyeecheung
  • Nest.js 成最大赢家, github.com/nestjs/nest..., 让我想起了 "不要闹, 一切会慢慢变好" 的笑话

先说 --moduleResolution, 可选性比较少

  • node16 = nodenext; 但 nodenext 是扩展目标, 即未来如果有 node32, nodenext 会对齐到 node32
  • bundler
    • 需要 --module 设置为 es序列, 如 esnext
    • 支持 node16 规则
    • 但执行更宽松的 esm 规则: 可以不带后缀名
    • 但执行更宽松的模块路径: dir module, dir index module
    • 因为宽松, TypeScript 将 --moduleResolution bundler 描述为 infectious (传染性): 使用 tsc + --moduleResolution bundler 编译的库只能在 --moduleResolution bundler 的 App 环境中使用

Legacy --moduleResolution

  • classic
  • node10 = node; node deprecated

结论

  • node deprecated 后面会移除
  • classic 和 node10 也不再推荐使用
  • 能用到的会是 node16=nodenext, bundler

--module

  • es序列: es2015 / es2020 / es2022 / esnext
  • node系列: node16 / node18 / node20 / nodenext
  • preserve
  • commonjs
  • system amd umd 省略

--module es序列

版本

  • es6 = es2015
  • es2020: adds support for import.meta properties.
  • es2022: adds support for top-level await.
  • esnext: is a moving target that may include support for Stage 3 proposals to ECMAScript modules.

Note:

  • 数字版本 es6 = es2015. es2022 = es23, 数字太大且没有意义, 这种方式逐渐淘汰了!
  • Q: 为什么 module 没有 es2024 es2023 A: 这些版本没有 module 相关更改

--module node序列

node16 / node18 / node20 / nodenext

module target moduleResolution import assertions import attributes JSON imports require(esm)
node16 es2022 node16 ❌ ❌ N/A ❌
node18 es2022 node16 ✅ ✅ needs type "json" ❌
node20 ?(未找到文档) node16 ❌ ✅ needs type "json" ✅
nodenext (@2026.1) esnext nodenext ❌ ✅ needs type "json" ✅
Changelog
  • node16: since TypeScript 4.7
  • node18: since TypeScript 5.8, adds support for import attributes
  • node20: adds support for require(ESM).
实例
ts 复制代码
/* eslint-disable import/no-duplicates */

import pkgAssertion from '../package.json' assert { type: 'json' }
import pkgAttribute from '../package.json' with { type: 'json' }
console.log(pkgAssertion, pkgAttribute)

// `--module node16`
// Import assertions are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'.
// Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'.

// `--module node18`
// Cannot find module '../package.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.

// `--module node20`
// Import assertions have been replaced by import attributes. Use 'with' instead of 'assert'.

// `--module nodenext`
// Import assertions have been replaced by import attributes. Use 'with' instead of 'assert'.
Notes
  • import assertions 是 import attributes 的曾用名
  • moduleResolution = node16 / nodenext, 现在 --moduleResolution node16 = --moduleResolution nodenext
  • node20 & nodenext 还隐含了 --resolveJsonModule
  • Q: 都是 esm 模块规范, 有的体现在了 node16 node18, 有些体现在了 es2020 es2022 ? A: 可能是还没完成规范
--module node序列 意义在哪?
  • --module commonjs & --module es序列 有明确的语义, 代表: cjs & esm
  • --module node序列, 需要根据 package.json type 决定 emit 类型, 这是 Node.js 使用的规则, 故起名为 node序列
  • node.js or V8 支持了一些还没有进入 es 规范的特性, TypeScript 使用 --module node序列 表示这个暂时的状态

--module preserve

不改变模块语法, 交给 bundler 处理

Implies:

  • --moduleResolution bundler
  • --esModuleInterop

组合

--moduleResolution 条件 --module 结论
--moduleResolution bundler 时 --module 只能为 preserve or es2015 es2020 es2022 esnext
--moduleResolution node16 或 nodenext 时 --module 只能为 node16 or node18 or node20 or nodenext

决策树

新代码只使用 esm, 这里只讨论 esm 的情况

非常短的版本: 不用管 moduleResolution, 用设置的 module 值所决定的默认值即可

  • bundler: module: preserve
  • 非 bundler: module: nodenext

TotalTypeScript TsConfig Cheatsheet

www.totaltypescript.com/tsconfig-ch... and github.com/total-types...

相关推荐
mbshqqb11 小时前
TypeScript基础教程之同步生成器
前端·javascript·typescript
濮水大叔1 天前
Cabloy 双引擎架构详解:Vona 与 Zova 是如何协作的
typescript·node.js·全栈
前端大斗师1 天前
「大于 1000」把 1000 元那单也算进去了:我在 Vue3 订单页对了 10 句话
前端·人工智能·typescript·大模型·原力计划
GlobalAIagent1 天前
外贸站上线前的技术自查清单:漏一项询盘可能消失
google·typescript·ar·go语言·seo
半糖程序员2 天前
从零构建 Agent(11):压缩过长的上下文
typescript·agent
whi2 天前
一个小工具,解决了一个困扰 Vue 开发者多年的类型检查难题
vue.js·typescript
shmily麻瓜小菜鸡2 天前
Axios 中 params 与 data 的区别与原理
javascript·typescript
nyaomaru3 天前
将一个真实的 TypeScript OSS 库从 tsup 迁移到 tsdown
前端·typescript
wflynn3 天前
GitHub 今日推荐|ts-rust:把微软 TypeScript-Go 编译器逐行移植成 Rust 实现
rust·typescript·开源·github·compiler·tsc
Duang007_4 天前
生产可观测性:从“系统慢“到“根因“的完整链路(Go / TypeScript)
后端·python·golang·typescript·prometheus