Daotin

npm依赖的子依赖升级导致项目报错怎么办?用overrides解决

背景

今天早上刚上班,后收到测试发来的一张图,测试环境构建异常,报了一个错误。

Photo

具体错误的位置是:

plain text
require() of /root/.jenkins/workspace/1475-001-build-test-html-nginx/app/node_modules/brilliant-errors/node_modules/callsites/index.js from /root/.jenkins/workspace/1475-001-build-test-html-nginx/app/node_modules/brilliant-errors/dist/index.cjs is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.

Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /root/.jenkins/workspace/1475-001-build-test-html-nginx/app/node_modules/brilliant-errors/node_modules/callsites/package.json.

但是本地并没有复现,于是从仓库拉了最新的代码,在本地构建打包,果然出现了上面的问题。

分析

既然之前本地没有问题,重新构建的有问题,肯定是安装的包不同了,但是因为package.json是相同的,那么肯定是package-lock.json是不同的,对比了下果然有很大的差异。

因为差异太大,所以就从报错信息入手,找到了callsites这个包,经过对比,确实不同。那么只需要锁定之前的版本就好了,于是我就想,从callsites入手,一直往上找,看哪个包的版本不一样,于是找到了brilliant-errors 这个包,这个包的版本从0.6.0升级到了0.6.1,再往上就没有变化了。

于是,我尝试手动安装brilliant-errors 0.6.0版本的到项目中,然后再次打包,果然构建成功。

这时候其实已经可以解决问题了,但是因为不是项目需要的包,安装这个包会给人造成歧义。于是思考有没有更好的方案。

在网上和微信群寻求帮助,有群友提到了resolutions关键字。

然后我就去搜了一下是什么东西。

package.json 文件里的 resolutions 字段用于解析选择性版本,当我们通过yarn安装的依赖的时候,会安装resolutions 中依赖指定的版本。

参考文档:https://chore-update–yarnpkg.netlify.app/zh-Hans/docs/selective-version-resolutions

这个正好可以解决我遇到的这个问题。于是我去搜了一下npm可不可以使用resolutions ,然后找到了这篇文章:https://blog.csdn.net/cxwtsh123/article/details/123134278

需要安装一个npm-force-resolutions 依赖,然后配置scripts:

bash
"scripts": {
  "preinstall": "npx npm-force-resolutions"
}

然后就可以已正常npm install 的方式来安装了。

经过尝试,发现不起作用,现在也没找到原因。

继续找方案,偶然发现npm有个overrides属性,可以实现类似resolutions 的功能,写法也是一样的:

bash
"overrides": {
  "brilliant-errors": "0.6.0"
}

试了一下,完美解决问题。

但是需要注意的是,overrides需要npm≥v8.3 才支持。

为了让测试在配置好node的时候,就配置好npm,我们选择了配置套的node,而不需要单独安装npm 的版本。

经过对比,选择了下面的方案:

Photo
plain text
E:\whty-code\BlueLink>npm -v
8.19.2

E:\whty-code\BlueLink>node -v
v16.18.1
PS:我还在brilliant-errors仓库提了issue,看到也有人遇到类似的问题,因为0.6.1正好的前几天刚提交的,出问题还是很有可能的。看作者啥时候能修复掉。