前言
在npm版本7以上时,npm install时出现类似如下报错:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: ant-design-pro@4.0.0
npm ERR! Found: antd@3.26.20
npm ERR! node_modules/antd
npm ERR! antd@"^3.23.6" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer antd@"4.x" from @ant-design/pro-layout@4.11.4
npm ERR! node_modules/@ant-design/pro-layout
npm ERR! @ant-design/pro-layout@"^4.10.13" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /Users/liufang/.npm/eresolve-report.txt for a full report.
应该如何解决?其根本原因是为何?本文一一解答。
解决方案
分为粗暴解决和真正解决。
粗暴方案
粗暴解决的话,只需要npm install --legacy-peer-deps
绕过 npm 对 peerDependencies的检测报错即可,或者在.npmrc中配置legacy-peer-deps=true
。但是这种方式的话,其实是留着隐患,因为peerDependencies本来就是各个三方包声明的各种预依赖的包版本,现在报错了说明依赖关系存在问题。最好是可以真正解决。
真正方案
在通过上面的手段绕过安装后,通过npm ls -a
来分析依赖包关系,该命令会列出所有的依赖及子依赖,并将peer的报错完整列出,结果如下:
npm ERR! peer dep missing: eslint@^7.32.0 || ^8.2.0, required by eslint-config-airbnb-base@15.0.0
npm ERR! peer dep missing: eslint-plugin-import@^2.25.2, required by eslint-config-airbnb-base@15.0.0
npm ERR! peer dep missing: react@>=16.9.0, required by use-json-comparison@1.0.6
npm ERR! peer dep missing: react@>=16.9.0, required by use-media-antd-query@1.1.0
npm ERR! peer dep missing: @babel/core@>=7.11.0, required by @babel/eslint-parser@7.22.9
npm ERR! peer dep missing: eslint@^7.5.0 || ^8.0.0, required by @babel/eslint-parser@7.22.9
npm ERR! peer dep missing: eslint@^6.0.0 || ^7.0.0 || ^8.0.0, required by @typescript-eslint/eslint-plugin@5.62.0
npm ERR! peer dep missing: eslint@^6.0.0 || ^7.0.0 || ^8.0.0, required by @typescript-eslint/parser@5.62.0
npm ERR! peer dep missing: eslint@>=7.0.0, required by eslint-config-prettier@8.9.0
npm ERR! peer dep missing: eslint@^7.0.0 || ^8.0.0, required by eslint-plugin-promise@6.1.1
npm ERR! peer dep missing: eslint@>=7.0.0, required by eslint-plugin-unicorn@20.1.0
npm ERR! peer dep missing: prettier@>= 2.0.0, required by prettier-plugin-two-style-order@1.0.1
npm ERR! peer dep missing: eslint@^6.0.0 || ^7.0.0 || ^8.0.0, required by @typescript-eslint/utils@5.62.0
npm ERR! peer dep missing: eslint@^6.0.0 || ^7.0.0 || ^8.0.0, required by @typescript-eslint/utils@5.62.0
npm ERR! peer dep missing: eslint@^6.0.0 || ^7.0.0 || >=8.0.0, required by @eslint-community/eslint-utils@4.4.0
npm ERR! peer dep missing: @babel/core@^7.13.0, required by @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.5
npm ERR! peer dep missing: @babel/core@^7.12.0, required by @babel/plugin-transform-class-static-block@7.22.5
npm ERR! peer dep missing: eslint@>=7.0.0, required by eslint-template-visitor@2.3.2
npm ERR! peer dep missing: @babel/core@>=7.11.0, required by @babel/eslint-parser@7.22.9
npm ERR! peer dep missing: eslint@^7.5.0 || ^8.0.0, required by @babel/eslint-parser@7.22.9
npm ERR! peer dep missing: postcss@^8.0.4, required by postcss-sorting@6.0.0
npm ERR! peer dep missing: eslint-plugin-react-hooks@1.5.0, required by eslint-config-umi@1.6.0
npm ERR! peer dep missing: @typescript-eslint/eslint-plugin@2.x, required by eslint-config-react-app@5.0.2
npm ERR! peer dep missing: @typescript-eslint/parser@2.x, required by eslint-config-react-app@5.0.2
npm ERR! peer dep missing: eslint@6.x, required by eslint-config-react-app@5.0.2
npm ERR! peer dep missing: eslint-plugin-flowtype@3.x, required by eslint-config-react-app@5.0.2
npm ERR! peer dep missing: eslint-plugin-react-hooks@1.x, required by eslint-config-react-app@5.0.2
npm ERR! peer dep missing: react@^16.14.0, required by react-test-renderer@16.14.0
npm ERR! peer dep missing: @babel/core@^7.13.0, required by @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.5
npm ERR! peer dep missing: @babel/core@^7.12.0, required by @babel/plugin-transform-class-static-block@7.22.5
npm ERR! peer dep missing: react@>=16.9.0, required by rc-util@5.35.0
npm ERR! peer dep missing: react-dom@>=16.9.0, required by rc-util@5.35.0
npm ERR! peer dep missing: dva@^2.5.0-0, required by dva-immer@0.4.5
npm ERR! peer dep missing: redbox-react@1.x, required by babel-plugin-dva-hmr@0.4.2
npm ERR! peer dep missing: dva-core@^1.1.0 | ^1.5.0-0 | ^1.6.0-0, required by dva-loading@3.0.6
npm ERR! peer dep missing: react@^16.18.4, required by dva@2.6.0-beta.6
npm ERR! peer dep missing: react-dom@^16.18.4, required by dva@2.6.0-beta.6
再对应着这个报错信息一一修复,才是真正解决了依赖的问题。
关键词解释
对上文中的一些关键词进行解释,方便不明白的用户理解。
peerDependencies
peerDependencies
是指某个依赖包所依赖的另外一个包,但是这个依赖包必须由应用程序或者插件来提供,而不能由该依赖包自己来安装和提供。也就是说,peerDependencies
是指这个依赖包在运行时需要与其他包进行协作,但是这些包不会被安装到该依赖包的 node_modules
目录下。
举个例子,假设你正在开发一个 react
组件库,你的组件依赖于 react
和 prop-types
包,但是你不想在组件库中再次安装这些包,而是希望使用应用程序或者插件中已经安装的这些包。在这种情况下,你可以将 react
和 prop-types
声明为 peerDependencies
,以便在组件库中使用这些包。
在安装依赖包时,npm
会检查依赖包的 peerDependencies
,并验证它们是否已经被安装。如果没有,npm
会发出警告,npm7以上会直接报错,就是本文讲到的报错,提醒用户需要手动安装这些依赖包。这样可以确保依赖包在运行时能够正常地与其他包协作。
需要注意的是,虽然 peerDependencies
不会被安装到依赖包的 node_modules
目录下,但是它们仍然可以被该依赖包的代码所引用。因此,应该确保这些 peerDependencies
能够在应用程序或者插件中正确地安装和使用。
npm ls
npm ls 命令用于列出当前项目的所有依赖包及其版本信息。
当你在项目的根目录下执行 npm ls 命令时,npm 会递归地列出所有依赖包的名称、版本号、依赖关系等信息,并以树形结构展示。
此外,npm ls 命令还支持以下选项:
–depth=:指定递归的深度,默认为 0,表示只列出当前项目的直接依赖包。如果设置为 1,则会列出当前项目的直接依赖包以及它们的依赖包,以此类推。
–global:列出全局安装的依赖包。
–json:以 JSON 格式输出依赖包信息。
–long:输出详细的依赖包信息,包括依赖关系、版本号、描述等。
–parseable:以 Unix 风格的路径格式输出依赖包路径。
–production:只列出生产环境依赖包。
–development:只列出开发环境依赖包。
legacy-peer-deps
legacy-peer-deps 是 npm 7.x 中的一个特性,用于在安装依赖包时允许绕过 peerDependencies 检查。
在 npm 7.x 中,默认情况下会启用 peerDependencies 检查,这意味着当安装某个依赖包时,npm 会检查该依赖包的 peerDependencies 是否已经被安装,如果没有,会发出警告并提示手动安装这些依赖包。这个检查机制可以帮助开发者在安装依赖包时避免出现不兼容的情况,并提高代码质量。
然而,有些依赖包的 peerDependencies 是过时的或者不合理的,这可能会导致在安装时出现错误或者警告。为了解决这个问题,npm 7.x 引入了 legacy-peer-deps 特性,允许在安装依赖包时绕过 peerDependencies 检查。