Node.js 24.15 的 require(esm) 终于 stable 了,我第一时间把它跑通了

如果你被 npm 包的 CJS/ESM 双版本发布折磨过,今天这篇文章可能是你今年最值得花 5 分钟读的前端资讯。

上周 Node.js 24.15.0 LTS 悄悄更新了一个功能:require(esm) 从实验性标记正式毕业,变成了稳定特性。这意味着——在 Node.js 环境里,CommonJS 文件终于可以直接用 require() 加载一个纯 ESM 的包了,不用再配 type: module,不用再打两套产物,不用再和 package.json 的 exports/main/module 字段较劲。

过去几年这是什么体验?

大多数 npm 库为了兼容两边,会同时打 CJS 和 ESM 两个版本,package.json 里写一堆条件导出:

{
  "main": "dist/index.cjs",
  "module": "dist/index.mjs",
  "exports": {
    "import": "./dist/index.mjs",
    "require": "./dist/index.cjs"
  }
}

库作者累,CI 构建时间翻倍,产物包体积也大了一圈。而如果你写的应用想直接 require 一个只发 ESM 的包,抱歉,不支持。

require(esm) 解决的就是这个问题。它本质上是在 CommonJS 模块系统里嵌入了一个同步 ESM 加载器。Joyee Cheung(Node.js 模块系统的主要维护者)专门写过一篇实现细节,核心思路是给被加载的 ESM 模块加一个 __esModule 标记,然后用 module-sync 条件来协调两套导出语义。底层同步加载机制也经过重构,消除了之前和异步 import() 的竞态问题。

Node.js 24.15 LTS 这个版本特别值得关注,是因为它同时带了几个配套更新:V8 升级到 12.4(带来了 WebAssembly GC、Array.fromAsync、Set 的 union/intersection/difference 等),还有 Maglev 编译器默认启用。require(esm) 在这个节点 stable,时机刚好。

现在你具体怎么用?

第一步:确认你的 Node.js 版本 >= 24.15.0 LTS。如果用的是项目里的 nvm 或者 fnm:

nvm install 24
nvm use 24
node -v  # 确认 >= 24.15.0

第二步:找一个纯 ESM 的包,直接 require 进来试试。比如 valibot(一个 TypeScript schema 验证库,只发了 ESM 版本):

// CJS 文件里直接写
const { parse } = require(valibot);

const result = parse(
  [{ username: alice }],
  array(object({ username: string() }))
);
console.log(result); // [{ username: alice }]

不需要 package.json 加 type: module,不需要任何实验性 flag,直接跑。

第三步:如果你的团队有祖传 CJS 代码要逐步迁移到 ESM,现在可以用 require(esm) 作为过渡:

// 旧的 CJS 模块
module.exports = { foo: 1 };

// 新的 ESM 模块(main 指向它)
export const foo = 1;
export const bar = 2;

Consumer 侧只需要升级 Node.js 版本就行,改动最小。

有没有坑?

Joyee Cheung 在实现笔记里特别提到了「faux ESM」场景:有些包表面发的是 ESM,实际上是转译过的 CommonJS(标记了 __esModule)。require(esm) 对这类包的兼容逻辑比较复杂,如果你踩到了,建议先看官方文档的兼容列表,别硬上。

另外:require(esm) 是同步的,所以动态 import() 该用的时候还是得用,它解决的是「同步加载 ESM」这个具体问题,不是替代 ESM 的动态加载能力。

怎么判断该不该迁移?

如果你的团队还在维护双版本发布的 npm 包,或者有一堆祖传 CJS 代码等着逐步换 ESM,这个版本值得第一时间上。Node.js 26(今年 10 月正式 LTS)也会带这个特性,届时会是更稳妥的生产环境选择。

现在的推荐策略:开发环境用 Node.js 24.15 跑通,生产等 10 月 Node.js 26 LTS。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 26 阅读