require(esm)
最近在刚刚发布的
Node.js v22.12.0(LTS)
版本中,有一项比较重要的更新,这个版本默认启用了
require(esm)
。
在 v20.x 和 v22.x 版本中,通过命令行标志
--experimental-require-module
支持使用
require()
加载原生 ES 模块。而在 v23.x 版本中,这项功能默认开启。在此次发布中,v22.x 版本也不再需要通过标志来启用该功能。
现在这个功能虽然还处于实验阶段,但我们不再需要通过
--experimental-require-module
标志来启用它了。当 Node.js 实例首次在
require()
中遇到原生 ES 模块时,会发出实验性警告,除非
require()
的路径中包含
node_modules
。如果因为这个功能引发了任何回归问题,我们可以到 Node.js 的问题追踪器上报告。同时,可以使用
--no-experimental-require-module
标志来禁用该功能作为应急解决办法。
ES模块定义 (
esmModule.mjs
):
export function greet() {
console.log("Hello, ESM!");
}
在 Node.js v22.12.0 中,直接运行
app.js
将成功加载 ES 模块,而不会遇到报错。
const { greet } = require('./esmModule');
greet(); // 输出: Hello, code秘密花园!
我们还可以通过检查
process.features.require_module
来确认当前的 Node.js 实例是否启用了
require(esm)
支持。对于包,可以使用
module-sync
导出条件来检测当前 Node.js 实例是否支持
require(esm)
,允许同时使用
require()
和
import
加载相同的原生 ES 模块。
这一变化让广大 NPM 包作者发布原生 ESM 模块更加方便了,因为可以更少地对 CommonJS 用户造成破坏。
可能遇到的问题
但是,如果大家代码里有使用顶层
await
的模块可能会抛出
ERR_REQUIRE_ASYNC_MODULE
错误。除非从包含
node_modules
的路径加载,这个功能会发出实验性警告。
在之前的文章中有提到过这个:
注意,使用这个 API 可能导致你的 Node.js 出现兼容性问题!
当时提到的时候,大家需要跨越大版本(V23)才可能遇到这个问题,但是当前的更新后,在小版本升级中也可能会遇到这个问题了,大家需要尽快排查下有没有这个问题,来确保升级到这个版本后不会受到影响。
其他值得关注的更改