内容提要
Node.js 新增了 --experimental-default-type 和 --experimental-detect-module 标志,允许用户更改默认模块系统并自动检测 ES 模块语法。这一更新旨在提升性能和兼容性,鼓励开发者在 package.json 中添加类型字段以优化模块解析。
延伸解读
模块系统默认行为的改变
Node.js 20.10.0 引入 --experimental-default-type 标志,允许将默认模块系统从 CommonJS 切换为 ES 模块。启用后,原本隐式视为 CommonJS 的输入(如无 package.json 的 .js 文件、--eval 或 STDIN 字符串)会被解释为 ES 模块。但已显式声明类型的文件不受影响,例如通过 package.json 的 type 字段、.mjs/.cjs 扩展名或 --input-type 标志指定的模块。
自动检测 ES 模块语法
新增的 --experimental-detect-module 标志可自动检测并运行 ES 模块。对于“模糊”文件(即 .js 或无扩展名文件,且没有带 type 字段的 package.json),Node.js 会解析文件内容以检测 ES 模块语法;若找到则作为 ES 模块运行,否则作为 CommonJS 模块运行。该检测同样适用于 --eval 或 STDIN 的字符串输入。官方希望未来版本默认启用检测,但检测会增加启动时间。
优化启动时间的建议
由于模块检测会增加启动时间,Node.js 鼓励开发者(尤其是包作者)在 package.json 中显式添加 type 字段,即使默认值为 "type": "commonjs"。存在 type 字段或使用 .mjs/.cjs 等显式扩展名时,将跳过检测流程,从而避免解析开销,提升模块解析效率和启动速度。
其他值得关注的更新
本次发布还包含多项改进:fs.writeFile 系列函数新增 'flush' 选项,确保写入成功后数据立即刷新到永久存储;新增 --experimental-websocket 标志提供 WHATWG 标准的 WebSocket 全局对象;修复了 vm.Script 在启用 importModuleDynamically 时的编译缓存性能回归,使受影响的用户(尤其是 Jest 用户)可升级;同时继续推进 vm.CompileFunction 的编译缓存支持。
Q&A
Node.js 20.10.0 新增了哪些实验性标志?
新增了 --experimental-default-type 和 --experimental-detect-module 标志。
如何使用 --experimental-default-type 标志?
使用 --experimental-default-type=module 时,隐式的 CommonJS 将被解释为 ES 模块。
什么是 --experimental-detect-module 标志的功能?
该标志可以自动检测 ES 模块语法并运行相应的模块。
为什么建议开发者在 package.json 中添加类型字段?
添加类型字段可以优化模块解析和启动时间,尤其是在使用新标志时。
Node.js 如何处理没有 package.json 的模糊文件?
Node.js 将解析文件以检测 ES 模块语法,如果找到则作为 ES 模块运行,否则作为 CommonJS 模块运行。
使用 --experimental-default-type 标志会对现有代码产生什么影响?
现有代码中明确指定为 ES 模块或 CommonJS 的输入不会受到影响,隐式的 CommonJS 会被解释为 ES 模块。