使用top-level await时CircleCI执行报错解决方案
问题根因
这个报错和浏览器对top-level await的支持度没有关系——CircleCI任务里的构建、测试、脚本执行步骤是跑在Node.js运行时,不是浏览器环境。cimg/node:current-browsers镜像虽然预装了最新版浏览器,但如果Node侧的模块解析规则、工具配置没适配top-level await,就会抛出这个语法错误。
常见触发原因:
- 执行的脚本是CommonJS(CJS)格式,Node默认的CJS模块规范原生不支持top-level await
- 项目用的测试、构建工具(比如低版本Jest、Babel、Webpack4)默认没开启top-level await语法解析
- 镜像拉取异常导致内置Node版本实际低于14.8.0——top-level await在Node 14.8.0之后才进入原生支持范围
可行解决方案
方案1:调整Node模块配置(改造成本最低)
如果报错是直接执行node 脚本文件时抛出的:
- 全项目适配ESM:在项目根目录
package.json里添加配置,把项目默认模块格式改为ESM:{ "type": "module" } - 单脚本适配:如果不想改动全项目模块规则,直接把用到top-level await的脚本后缀改为
.mjs,Node会自动识别这类文件为ESM模块,原生支持top-level await语法,不需要额外配置。
方案2:指定稳定版本的CircleCI镜像
不要用current这类浮动标签的镜像,避免版本漂移问题,直接指定Node 18/20这类LTS版本的带浏览器镜像即可,比如:
docker: - image: cimg/node:20.17-browsers
这类版本的Node对ESM、top-level await的支持已经非常稳定,不会出现版本不匹配的问题。
方案3:调整构建/测试工具配置
如果报错是出在跑单元测试、打包构建的步骤(不是直接执行node脚本),对应调整工具配置即可:
- Jest:升级到28及以上版本,在jest配置中添加
testEnvironmentOptions: { customExportConditions: ['node', 'node-addons'] },同时确保package.json中已设置"type": "module" - Babel:安装
@babel/plugin-syntax-top-level-await依赖,在babel配置文件的plugins数组中启用该插件 - Webpack:升级到5及以上版本,在webpack配置中设置
experiments.topLevelAwait = true
快速验证方法
配置改完后可以在CI流程里加两步前置校验,先确认基础Node环境支持正常:
steps: - checkout - run: node -v # 确认版本号 >=14.8.0 - run: echo "const val = await Promise.resolve('tla ok'); console.log(val)" > check-tla.mjs && node check-tla.mjs
如果这步能正常输出tla ok不抛语法错,说明基础Node环境已经适配完成,剩余报错就是对应构建/测试工具的配置问题,按方案3调整即可。
内容的提问来源于stack exchange,提问作者backspaces
相关产品推荐
相关产品推荐

