假如你的项目里包含子项目(packages), 且子项目 A 包含一个 peer dependency 依赖的包 xxx@1.2.1
版本,而子项目 B 包含一个 peer dependency 依赖了同样的包,但是版本是 xxx@1.3.2
。
当你尝试通过npm 安装时,你可能会遇到一个常见的错误信息,上面写着 Conflicting peer dependency:xxx
,详细错误信息类似于:
Conflicting peer dependency: xxxx@1.2.1
node_modules/xxx
peer xxx@"^1.2.1" from 项目A
... ...
或者是直接报了如下错误:
满屏的 npm ERR!
, 意思是说无法解析依赖树。
它也「细心」地给了你解决方式:
安装的时候,增加**
--force or --legacy-peer-deps
**参数
Why:为啥出现 peer dependency 冲突的错误呢?
这一切还要从 npm
版本差异 说起,说之前先让我们了解一些peer dependency
概念。
What: 什么是 peer dependency?
一个 peer dependency 依赖指定了该项目的这个包,要求父级环境具有这个包,而它自己不是直接依赖它。举例:项目 A 安装依赖 react@16.8
:
{
"dependencies": {
"react": "^17.0.2",
"libB": "^1.2.0"
}
}
而 libB的 package.json 如下:
{
"peerDependencies": {
"react": ">=16.8.0"
}
}
那么安装后的项目结构如下:
项目A
|
+---node_modules
+---react
package.json
|
+---libB
package.json
那么为什么 libB 不把"react": "16.8.0"
放到dependencies
中呢?
假如 libB 放到dependencies
的话,项目 A 安装后的结构如下:
项目A
|
+---node_modules
+---react
package.json
|
+---libB
package.json
+---react
package.json
可以看到项目 A 安装了了两个不同版本的 react
, 而peerDependencies
仅有一个react
版本。
那么peerDependencies的一个作用就是减少重复安装依赖
在了解了基础概念后,让我们看看 npm 不同版本间的peer诡异行为
npm 不同版本上 peer 诡异行为
-
版本 1~3,
peerDependencies
会像dependencies
一样,被自动安装。 -
版本 4~6,由于重复数据删除算法的技术问题,npm停止支持
peerDependencies
的自动安装。如果出现依赖包版本冲突或缺失,只会发出警告,类似于: -
版本 7,npm 通过依赖Arborist算法:
- 默认自动安装
peerDependencies
- npm模块必须指定每个
peer dependency
的特定版本。
与之前的NPM版本相比,NPM版本7或更高版本对
peerDependencies
的要求要严格得多。这就是是本文开头提到的Conflicting peer dependency
错误的原因。 - 默认自动安装
-
版本 8,为了区别可选的 peer 与 必须的 peer,新增了 peerDependenciesMeta 字段来标记可选 peer。
到这里大家也知道罪魁祸首是谁了,下面让我们看看怎样解决这个 **Conflicting peer dependency
错误
修复 Conflicting peer dependency
ERR
使用以下几个方案可以解决这个冲突问题:
-
升级冲突包
检查npm返回的错误,找出导致错误的包,并使用
npm install
命令手动升级新版本。需要注意的是:升级到软件包的新版本可能需要大量的工作,特别是当涉及到主要的版本更改时。这可能会导致应用程序出现新的错误和不稳定。 -
使用
--legacy-peer-deps
选项。--legacy-peer-deps
是在NPM 7中引入进来的选项,用来忽略peer dependency
,并继续安装。它将告诉 npm 安装包时使用npm 6算法来解析peerDependencies
,也就是不自动安装peer dependency
。为了避免每次启动
npm i
命令时都添加--legacy-peer-deps
标志,你可以在项目的根文件夹中创建一个.npmrc
文件,并将其初始化如下,npm i
命令将自动包含--legacy-peer-deps
标志
legacy-peer-deps=true
-
使用Yarn代替npm
Yarn是npm的替代包管理器。具体来说,与npm相比,它有一个更有效的冲突解决系统。因此,在解决对等依赖时,Yarn使用了比NPM更好的算法。因此,切换到Yarn可能会解决这个问题
-
清理npm
由于npm缓存模块中的问题导致的
peer dependency
错误。如果前面的方法都不起作用,请尝试进行一个干净的包安装。参考一下步骤:- 删除
node_modules
文件夹中。 - 删除
package-lock.json
- 清除 npm 缓存:
npm cache clean --force
- npm install
- 删除