bug描述

在cesium+vue3项目开发时,安装依赖后跑不起来,报错提示如下:

排错过程:

根据错误提示知道:Cesium引用了@zip.js/zip.js中的zip-no-worker.js文件,推测可能是@zip.js/zip.js的版本无正确,导致cesium拿不到这个引用的文件。

于是到node_modules中查看了@zip.js/zip.js依赖的文件夹:

果然没有,验证了我的推测,于是又查看了cesium中依赖的zip包版本,和实际安装的zip包版本,进一步确认了两者的版本不一致:

问题解决

1.先用了npm,把@zip.js/zip.js包删了以后,想用npm i命令指定版本安装一下,发现npm报错,很离谱。

2.直接放弃npm,选择了pnpm安装依赖,在package.json中添加一项配置,强制项目中所有对@zip.js/zip.js的依赖使用该版本:

1
2
3
4
5
"pnpm": {
"overrides": {
"@cesium/engine>@zip.js/zip.js": "2.7.34" //使用依赖选择器,精准指定@cesium/engine包使用的@zip.js/zip.js依赖的版本
}
}

然后重启项目,成功解决!

拓展:

为什么安装依赖时,会出现依赖冲突呢?咨询AI哥后,了解到依赖冲突出现最常见的原因是——项目直接或间接依赖了同一个库的不同版本:

1
2
3
4
5
项目A
├── 库B v1.0
│ └── 库D v2.0
└── 库C v2.0
└── 库D v1.0

而npm的依赖解析策略是:

1. 版本兼容性检查

npm 使用语义化版本(SemVer)规范来解析依赖版本。当遇到同一个包的不同版本时,npm 会:

  • 检查版本范围是否有交集
  • 如果版本兼容,选择满足所有要求的最高版本
  • 如果版本不兼容,则分别安装不同版本

2. 扁平化安装策略

从 npm v3 开始,npm 采用了扁平化安装策略来避免”依赖地狱”问题:

扁平化规则:

  • 将依赖尽可能提升到项目根目录的 node_modules
  • 当遇到版本冲突时,回退到嵌套安装方式
  • 优先将高版本或先安装的依赖放在顶层

3. 安装顺序影响

npm 的安装顺序会影响最终的依赖结构。例如:

了解到以上的关键信息后,不难发现本次bug出现的原因:

Cesium在package.json中指定了@zip.js/zip.js包的版本为2的大版本,没有锁定小版本2.7,而项目中有其他依赖包也使用了@zip.js/zip.js包,且版本为2.8.10。npm将2.8.10提升到了顶层node_modules中(因为cesium的package.json文件告诉它cesium兼容所有大版本为2的@zip.js/zip.js包,这是允许的),而事实上,@zip.js/zip.js包在2.8.10中,文件结构发生了变化,导致Cesium想引用的文件在该版本中找不到(不兼容),于是bug发生了。