Node从12升级到16报错:循环依赖访问不存在的splice属性致程序中断
问题根因
Angular CLI 11.1.2 官方最高兼容 Node.js 14 版本,Node 16 收紧了 CommonJS 模块循环依赖的校验逻辑:Node 12 中循环依赖场景下访问模块不存在导出属性的行为会被静默忽略,Node 16 会直接抛出警告,若对应代码是旧版依赖/业务代码中在模块加载阶段直接调用数组splice方法的逻辑,会直接打断模块初始化流程,导致后续 Promise 链未被正常注册,程序执行中断。
排查解决步骤
- 优先做版本兼容对齐
最稳妥的方案是将 Node 版本降级到 14.x(Angular CLI 11 的官方推荐运行版本),使用 nvm 管理版本的话直接执行以下命令:
之后删除项目下的nvm install 14 nvm use 14node_modules文件夹和package-lock.json文件,重新执行npm install安装依赖,绝大多数场景下问题会直接修复。 - 定位业务代码中的循环依赖
从错误栈可以直接定位触发点在apis/admin/component.js的第1、2行,循环链路是apis/admin/index.js第44行引用了component.js,而component.js前两行又反向引用了index.js或其导出的属性,形成了循环引用。
把两个文件互相引用的公共逻辑抽离到第三个独立的工具/配置文件中,打破双向引用的循环链路即可。 - 修复第三方依赖兼容问题
如果循环依赖来自node_modules中的旧版本依赖而非业务代码:- 执行
npm ls <包名>定位对应依赖的版本,优先将依赖升级到兼容Node 16的版本,注意不要跨大版本升级Angular相关包,避免引发其他兼容问题 - 临时调试阶段可以在启动命令中添加参数,跳过循环依赖警告的抛出,避免模块加载被打断:
注意:该方式仅为临时屏蔽方案,没有解决根本的循环依赖问题,不建议在生产环境使用node --no-warnings=CircularRequire 你的启动入口文件路径 - 执行
- 定位Promise中断的具体位置
如果完成以上步骤后程序依然中断,可以在项目启动入口文件的最顶部添加全局异常监听,捕获未被处理的异常定位具体断点:process.on('unhandledRejection', (reason, promise) => { console.log('未处理的Promise拒绝:', promise, '异常原因:', reason); }); process.on('uncaughtException', (err) => { console.log('未捕获的全局异常:', err); });
内容的提问来源于stack exchange,提问作者Anoop Chaudhary
相关产品推荐
相关产品推荐

