You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Node.js v16未将文件视为独立模块?版本差异疑问

Node.js v16下顶级await报错的原因与解决办法

Node.js v18官方文档说明“每个文件都被视为独立模块”,但在v16环境运行以下代码时,会触发报错:SyntaxError: await is only valid in async functions and the top level bodies of modules。

涉及代码

init.js

module.exports.TESTING = (process.argv[2] == 'test');
async function init() {
    let ss = require('./safestore.js');

    let p = await ss.safestore.read();
    return p;
}
await init();

it.js

require('./init.js');

执行命令 node it.js test 会触发上述报错,将init.js最后一行改为(async () => { await init(); })();则可正常运行。

原因解析

核心是Node.js v16与v18的模块机制差异:

  • Node.js v18默认将.js文件识别为ES模块,天然支持顶级await(模块顶层直接使用await);
  • v16中,.js文件默认是CommonJS模块,CommonJS模块不支持顶级await,只有明确声明为ES模块的文件(比如后缀改为.mjs,或在项目根目录package.json中设置"type": "module")才能使用顶级await;
  • 用require()加载init.js属于CommonJS加载方式,此时init.js会被当作CommonJS模块处理,顶层的await init()不符合语法规范;
  • 改成async立即执行函数能运行,是因为把await放在了合法的async函数作用域内,这在CommonJS模块中是允许的。

误区纠正

有人认为这是.js与.mjs后缀的差异,但本质并非如此——关键在于Node.js版本对模块默认处理逻辑的调整,v18改变了默认行为,而v16仍沿用旧规则。

内容的提问来源于stack exchange,提问作者Dave Scotese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:25:15