PNPM 安装包时为什么会出现 missing peer xxx

8,485 阅读10分钟

如下图所示,使用pnpm安装 antd出现了如下提示

 WARN  Issues with peer dependencies found
.
├─┬ @testing-library/user-event 13.5.0
│ └── ✕ missing peer @testing-library/dom@>=7.21.4
└─┬ react-scripts 5.0.1
  └─┬ eslint-config-react-app 7.0.1
    └─┬ eslint-plugin-flowtype 8.0.3
      ├── ✕ missing peer @babel/plugin-syntax-flow@^7.14.5
      └── ✕ missing peer @babel/plugin-transform-react-jsx@^7.14.9
Peer dependencies that should be installed:
  @babel/plugin-syntax-flow@^7.14.5
  @babel/plugin-transform-react-jsx@^7.14.9
  @testing-library/dom@>=7.21.4

怎么回事,那我用npm install antd试一下

npm WARN antd@4.23.2 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN antd@4.23.2 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN @ant-design/react-slick@0.29.2 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-cascader@3.7.0 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-cascader@3.7.0 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN @ant-design/icons@4.7.0 requires a peer of react@>=16.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN @ant-design/icons@4.7.0 requires a peer of react-dom@>=16.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-drawer@5.1.0 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-drawer@5.1.0 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-checkbox@2.3.2 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-checkbox@2.3.2 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-collapse@3.3.1 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-collapse@3.3.1 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-dialog@8.9.0 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-dialog@8.9.0 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-dropdown@4.0.1 requires a peer of react@>=16.11.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-dropdown@4.0.1 requires a peer of react-dom@>=16.11.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-field-form@1.27.1 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-field-form@1.27.1 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-picker@2.6.10 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-picker@2.6.10 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-input@0.1.2 requires a peer of react@>=16.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-input@0.1.2 requires a peer of react-dom@>=16.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-mentions@1.9.2 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-mentions@1.9.2 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-notification@4.6.0 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-notification@4.6.0 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-menu@9.6.4 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-menu@9.6.4 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-motion@2.6.2 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-motion@2.6.2 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-select@14.1.13 requires a peer of react@* but none is installed. You must install peer dependencies yourself.
npm WARN rc-select@14.1.13 requires a peer of react-dom@* but none is installed. You must install peer dependencies yourself.
npm WARN rc-pagination@3.1.17 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-pagination@3.1.17 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-image@5.7.1 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-image@5.7.1 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-table@7.26.0 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-table@7.26.0 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-progress@3.3.3 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-progress@3.3.3 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-rate@2.9.2 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-rate@2.9.2 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-resize-observer@1.2.0 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-resize-observer@1.2.0 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-segmented@2.1.0 requires a peer of react@>=16.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-segmented@2.1.0 requires a peer of react-dom@>=16.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-tree@5.7.0 requires a peer of react@* but none is installed. You must install peer dependencies yourself.
npm WARN rc-tree@5.7.0 requires a peer of react-dom@* but none is installed. You must install peer dependencies yourself.
npm WARN rc-trigger@5.3.1 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-trigger@5.3.1 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-upload@4.3.4 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-upload@4.3.4 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-slider@10.0.1 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-slider@10.0.1 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-steps@4.1.4 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-steps@4.1.4 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-switch@3.2.2 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-switch@3.2.2 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-tabs@12.1.0-alpha.1 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-tabs@12.1.0-alpha.1 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-textarea@0.3.7 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-textarea@0.3.7 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-tooltip@5.2.2 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-tooltip@5.2.2 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-tree-select@5.5.0 requires a peer of react@* but none is installed. You must install peer dependencies yourself.
npm WARN rc-tree-select@5.5.0 requires a peer of react-dom@* but none is installed. You must install peer dependencies yourself.
npm WARN rc-util@5.24.4 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-util@5.24.4 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-input-number@7.3.9 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-input-number@7.3.9 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-virtual-list@3.4.8 requires a peer of react@* but none is installed. You must install peer dependencies yourself.
npm WARN rc-virtual-list@3.4.8 requires a peer of react-dom@* but none is installed. You must install peer dependencies yourself.
npm WARN rc-overflow@1.2.8 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-overflow@1.2.8 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-align@4.0.12 requires a peer of react@>=16.9.0 but none is installed. You must install peer dependencies yourself.
npm WARN rc-align@4.0.12 requires a peer of react-dom@>=16.9.0 but none is installed. You must install peer dependencies yourself.

+ antd@4.23.2
added 62 packages from 32 contributors and audited 62 packages in 34.197s

2 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

my god,这么多警告,怎么活。

那为了搞清楚这个问题,我们需要先了解PeerDependencies 到底是个什么玩意?搞清楚为什么会missing,为什么这么多WARN?


PeerDependencies 是个什么玩意?

先翻译一下peer:

n.同龄人,同等地位的人,相匹敌的人;(英国)贵族
v.凝视,费力地看;隐现;<古>看见;<古>匹敌

所以翻译成中文应该是叫对等依赖

那再看一下peeDependencies在哪里出现过?

"name": "html-webpack-plugin",
  "peerDependencies": {
    "webpack": "^5.20.0"
  },
"name":"antd",
"peerDependencies": {
    "react": ">=16.9.0",
    "react-dom": ">=16.9.0"
},
"name":"@testing-library/user-event",
"peerDependencies": {
    "@testing-library/dom": ">=7.21.4"
  },

First 总结一下:
当我们在一些npm包当中中,用到一些核心的依赖,这些依赖又是跟顶部应用的依赖的一样的时候,会把这些放到peerDependencies当中。而且这个peerDependencies通常在插件当中出现。
Then 问题来了,为什么不能直接把这些依赖直接放到dependencies当中呢?

eg:
想象一下,您正在开发一个ReactApp,他依赖React,有两个插件plugin1,plugin2,他们也依赖React,如果在两个插件中使用dependencies,那么在npm install之后,依赖图是这样的

.
├── ReactApp
│   └── node_modules
│       ├── React
│       ├── plugin1
│       │   └── nodule_modules
│       │       └── React
│       └── plugin2
│       │   └── nodule_modules
│       │       └── React

从上面结构看到,React在顶层已经安装了一次,但是在plugin1 和 plugin2 中又进行了重复的安装,所以被安装了三次。
那这边的peerDependencies就是干这事情的,避免重复安装依赖
如果在plugin1和plugin中使用peerDependencies,那么再执行npm install之后,依赖图是这样的

.
├── ReactApp
│   └── node_modules
│       ├── React
│       ├── plugin1
│       └── plugin2

So, 这时候React包知会被安装一次

当peerDependencies的版本不一致怎么办

But, 如果这个时候plugin1 和plugin2依赖的 React库的版本不一样咋办? 例如:

"name":"ReactApp",
"dependencies": {
    "plugin1":"1.0.0",
    "plugin2":"1.0.0",
    "react":"18.2.0"
  }
"name":"plugin1",
"peerDependencies": {
    "react":"16.8.0"
  }
"name":"plugin2",
"peerDependencies": {
    "react":"18.2.0"
 }

这时候,在reactApp下执行npm i 会出现如下警告⚠️?

npm WARN plugin1@1.0.0 requires a peer of react@16.8.0 but none is installed. You must install peer dependencies yourself.

啥,让自己解决?

如何解决版本不一致问题

在 stackoverflow上找到一个回答如下:

Snipaste_2022-09-22_14-01-07.png

OK 我们在demo中尝试一下,
方法一:npm i --save-dev react@16.8.0 , 删掉node_modules目录,重新进行npm i,警告消失了。 但是多了一条这个警告

npm WARN The package react is included as both a dev and production dependency.

方法二: 使用npm-install-peers解决这个问题, 安装好此库之后根目录重新之心npm i,上一条警告消失了。
那为什么这两个方法能够 隐藏 这个问题,不同的版本的react又安装到哪里去了? 大大的问号??? 我没找到,还在研究,有知道大佬的评论区见...

但是以上方法对于使用pnpm安装pnpm i依然有如下报错

 ERR_PNPM_PEER_DEP_ISSUES  Unmet peer dependencies

.
└─┬ plugin2 1.0.0
  └── ✕ unmet peer react@18.2.0: found 16.8.0

hint: If you don't want pnpm to fail on peer dependency issues, add "strict-peer-dependencies=false" to an .npmrc file at the root of your project.

按照提示新建.npmrc文件,输入strict-peer-dependencies=false,重新进行pnpm i,错误变成了如下的WARN。
警告⚠️是啥意思,就是告诉你不一定会报异常,但是也不确定能一定能正常。所以本质上的问题是依然存在,项目依然存在风险。

 WARN  Issues with peer dependencies found
.
└─┬ plugin2 1.0.0
  └── ✕ unmet peer react@18.2.0: found 16.8.0

总结

所以说现在npm,pnpm本身并没很好的办法去解决库当中版本依赖不一致的问题,以上只是隐藏问题,并没有很好解决,终局还需要手动升级包或者插件
如我上面所说,警告⚠️就是告诉你不一定会报异常,但是也不确定能一定能正常。库当中的版本依赖不一致是有可能造成一些不不要的麻烦的,所以你看到如babel-loader, babel这些库在升级版本时候,官方要求多个库同步升级,否则会构建失败。

引申观点

最近有很多vue2的项目想要升级到vue3,但是并不能成功升级到vue3的项目,一方面vue3有了很多破坏性的api,自己本身项目需要进行重构,更夸张的是很多依赖的包是也是依赖vue2去构建的,周边的生态没有跟上vue3的升级速度,并且生态中有很多KPI导向的包留存市面上,维护了一版本之后就再也不维护。so 尤大大也说了,谨慎升级!
老弟曾经也尝试升级过react@15.6项目 到 react@16.8,一些项目成功了,一些项目没有成功,没有成功的项目有一些典型的特征,就是用了过多的开源库,这些开源库强依赖react版本,在react升级之后并没有跟进维护,导致升级失败。
所以在技术选型的时候为什么要选择生态繁荣的,有大公司参与的,大家知道原因了吧!