从一次依赖下载失败理解npm、yarn install策略
从一次依赖下载失败理解npm、yarn install策略
工具版本
nodejs: v14.21.2npm: 6.14.17yarn: 1.22.19
问题现象
在一次删除lock文件重新下载依赖时,原本能够正常下载的依赖,现在却报错:node版本太低,导致下载依赖失败。特记录此次问题出现的原因。
假设现在项目有两个依赖 marked, simplemde
1 | |
而simplemde 内部又依赖了marked
1 | |
发现marked有两个依赖版本marked@*, marked@^0.3.19, 也可以说项目添加marked依赖的目的就是为了控制simplemde中的依赖marked的版本。然而yarn在下载依赖的时候,将依赖中的子依赖也平铺开了下载。
此时:marked@* 指定的依赖版本是 5.0.4 而 自2023-05-02发布的marked@5.0.0开始, 对node的版本要求直接从 12 升至 18,导致engines.node版本校验不通过,下载报错。
1 | |
对比 npm 和 yarn 下载依赖
通过
npm install下载依赖 (npm version: 6.14.17)
1 | |
在package-lock.json中, 将marked 锁在 version: 0.3.19
通过
yarn下载依赖 (yarn version: 1.22.19)
1 | |
yarn.lock 中确有两个marked依赖版本
问题原因
而一开始在项目中指定marked: ^0.3.19也就是为了限制子依赖版本在0.3.*, 但是现在使用yarn下载会校验子依赖中的marked@*,导致下载中断, 但是使用npm下载却不会有这个问题。
虽然可以通过配置忽略版本校验,但是根本原因还是yarn重复校验下载了依赖。
了解yarn的install流程
Resolving packages: 分析包的依赖关系及版本信息Fetching packages: 下载依赖项,存储到缓存中Linking dependencies: 将缓存中的包扁平化的安装到项目当中去Building fresh packages: 构建安装, 执行install阶段的scripts
测试校验
- 首先清空缓存
yarn 查看缓存路径:yarn cache dir, 清空缓存:yarn cache clean --force
npm 查看缓存路径:npm config get cache, 清空缓存:npm cache clean --force
使用yarn下载,下载失败


这里倒是可以通过忽略
engines来通过下载
1 | |
npm install的过程发生了什么
当存在嵌套依赖和根级依赖冲突时,npm会根据以下规则来确定使用哪个依赖项:
- 直接依赖优先: 根级依赖的优先级更高,它们将覆盖任何嵌套依赖中的相同包。
- 版本范围解析: 如果根级依赖和嵌套依赖都有对同一个包的依赖,并且它们的版本范围不冲突,npm会尽量满足两者的依赖关系,并使用符合两者版本要求的最高版本。
- 版本冲突解析: 如果根级依赖和嵌套依赖对同一个包有不兼容的版本要求,npm会尝试解决版本冲突,通常会选择满足所有依赖关系的最高版本,并通过符号链接或软链接来确保正确的依赖关系。
npm如何解决有版本冲突的依赖包
现在我一个项目有两个依赖, marked@^0.3.19, 和 自己发的包 avatar0813-pkg-t
其中avatar0813-pkg-t包依赖 marked@^5.1.2



问题: node_modules 中的
avatar0813-pkg-t包中间还有个node_modules
这正是npm install解决版本冲突策略,因为两个依赖marked@^0.3.19,marked@^5.1.2版本不兼容导致的,两个依赖都要,但是不能扁平化安装

如果将
avatar0813-pkg-t包中依赖改为的marked@*以兼容外部版本则不会出现这个问题。
亦或这指定
resolutions依赖从而解决冲突
