摘要:带着好奇心,研究学习了一番npm install xxxx --legacy-peer-deps命令是什么?为什么可以解决下载时候产生的依赖冲突呢?

本文分享自华为云社区《npm install xxxx --legacy-peer-deps命令是什么?为什么可以解决下载时候产生的依赖冲突呢?》,作者: gentle_zhou 。

在日常使用命令npm install / npm install XX下载依赖的操作中,我经常会遇到无法解析依赖树的问题(依赖冲突):

但是每当遇到这种情况的时候,我用命令npm install --legacy-peer-deps就可以顺利进行下载操作:

这是为什么呢?带着好奇心,我去研究学习了一番npm install xxxx --legacy-peer-deps命令是什么?为什么可以解决下载时候产生的依赖冲突呢?(注:我本地当前正在使用的npm版本是8.6.0)

本文导航:什么是peerDependency?;npm install xxxx --legacy-peer-deps命令是什么?为什么可以解决下载时候产生的依赖冲突呢?;参考资料。

什么是peerDependency?

我们日常在前端项目开发过程中,见到最多的一定是package.json文件里的devDependencies(用于在开发环境下依赖的模块)和dependencies(无论开发环境还是生产环境都需要的依赖模块)这两个字段(感兴趣的小伙伴可以看我这篇文章:package.json文件里的dependencies和devDependencies有什么区别吗?)。

那么命令--legacy-peer-dep里的peerDependency是什么依赖呢?根据geeksforgeeks网站里的定义:

Peer Dependencies: In package.json file, there is an object called as peerDependencies and it consists of all the packages that are exactly required in the project or to the person who is downloading and the version numbers should also be the same. That is the reason they were named as peerDependencies. The best example is ‘react’ which is common in every project to run similarly.

翻译一下就是说,在package.json文件中,存在一个叫做peerDependencies(对等依赖关系)的对象,它包含了项目里需要的所有的包或则用户正在下载的版本号相同的所有的包(很绕,但意思就是对等依赖关系指定我们的包与某个特定版本的npm包兼容);对等依赖关系最好的例子就是React,一个声明式的创建用户界面的JS库。

那么我们为什么需要对等依赖关系呢?

假设我们现在有一个HelloHWCloud工程,已经在其根目录下的package.json文件中的dependencies字段里声明了packageA作为依赖,而其下面有两个项目app_A和app_B,它们也依赖packageA。如果我们用dependencies而不是peerDepenedencies来声明,那么npm install安装完项目之后的依赖结构如下图所示:

├── HelloHWCloud
│ └── node_modules
│ ├── packageA
│ ├── app_A
│ │ └── nodule_modules
│ │ └── packageA
│ └── app_B
│ │ └── nodule_modules
│ │ └── packageA

从上图可以看出,packageA依赖包被安装了3次,造成了2次安装冗余。

而如果采用peerDepenedency来下载,就可以避免这个核心依赖库被重复下载的问题。还是上面那个场景,我们在项目app_A和app_B的package.json文件里的peerDependencies字段声明一下核心依赖库packageA,然后在根目录的package.json文件里的dependencies字段也声明一下packageA。接着再执行npm install,生成的依赖结构就会如下图所示:

├── HelloHWCloud
│ └── node_modules
│ ├── packageA
│ ├── app_A
│ └── app_B

如上图所示,packageA就只会被安装一次。因此,npm 从版本v7开始,install就默认以peerDependencies的方式去下载了:

  1. 如果用户在根目录的package.json文件里显式依赖了核心库,那么各个子项目里的peerDepenedencies声明就可以忽略
  2. 如果用户没有显式依赖核心库,那么就按照子项目的peerDepenedencies中声明的版本将依赖安装到项目根目录里

而方式2就会导致一个问题:用户依赖的包版本与各个子项目依赖的包版本相互不兼容,那么就会报错(无法解析依赖树的问题(依赖冲突))让用户自行去修复,因而导致安装过程的中断。(因为是从npm v7引入的,因此npm v3-v6就不会发生这个错误)

npm install xxxx --legacy-peer-deps命令是什么?为什么可以解决下载时候产生的依赖冲突呢?

npm install xxxx --legacy-peer-deps命令与其说是告诉npm要去干什么,不如说是告诉npm不要去干什么。

legacy的意思:遗产/(软件或硬件)已过时但因使用范围广而难以替代的;而npm install xxxx --legacy-peer-deps命令用于绕过peerDependency里依赖的自动安装;它告诉npm忽略项目中引入的各个依赖模块之间依赖相同但版本不同的问题,以npm v3-v6的方式去继续执行安装操作。

所以其实该命令并没有真的解决冲突,而是忽略了冲突,以“过时”(v3-v6)的方式进行下载操作。

参考资料

  1. https://classic.yarnpkg.com/en/docs/dependency-types
  2. https://github.blog/2021-02-02-npm-7-is-now-generally-available/
  3. https://blog.logrocket.com/whats-new-in-npm-v7/
  4. https://stackoverflow.com/questions/66239691/what-does-npm-install-legacy-peer-deps-do-exactly-when-is-it-recommended-wh

点击关注,第一时间了解华为云新鲜技术~

npm install xxxx --legacy-peer-deps命令是什么?的更多相关文章

  1. npm install命令详解

    -S,–save 安装包信息将加到dependencies(生产阶段的依赖) npm install --save 或 npm install -S -D, –save-dev 安装包信息将加到dev ...

  2. npm install路径

    我们在webpack项目中使用npm install命令安装很多模块 但是很多时候都不知道这些模块安装在哪里,想要删除的时候找不到,所有想要明确的知道npm的安装路径 首先,npm install 安 ...

  3. npm install -S -D -g 有什么区别

    npm install module_name -S    即    npm install module_name --save    写入dependencies npm install modu ...

  4. centos7 laravel 项目 npm install报错

    npm install 初始化项目依赖的前端资源   报错 ERR xxx .. socket,symbol link is not supported ... 如果报错了 重新npm install ...

  5. npm常用命令学习(npm install -D,semver版本规范, npm进行版本管理的最佳实践用法)

    什么是npm npm有两层含义.一层含义是Node的开放式模块登记和管理系统,网址为npmjs.org.另一层含义是Node默认的模块管理器,是一个命令行下的软件,用来安装和管理Node模块. npm ...

  6. npm install的几种命令形式区别

    转自未来与传说.jigetage 我们在使用 npm install 安装模块的时候 ,一般会使用下面这几种命令形式: npm install moduleName # 安装模块到项目目录下 npm ...

  7. nodejs+express工程 在npm install之后或使用npm install bootstrap命令安装bootstrap之后

    nodejs+express工程 在npm install之后或使用npm install bootstrap命令安装bootstrap之后引入bootstrap文件 如果你的静态资源存放在多个目录下 ...

  8. Nodejs中npm install 命令的问题

    在使用nodejs的npm包管理工具中碰到过许多个坑,在网上查了很久才解决,现在加以总结. 两种安装方式(本地安装,全局安装) 1.全局安装(npm install -g moduleName/npm ...

  9. npm install命令对package-lock.json文件自动做了一些额外的更新

    今天我使用 npm 命令给项目安装file-saver,通过git却发现package-lock.json中除了file-saver组件之外的其他组件的记录也被改了 npm为何会自动做这些更改呢,又如 ...

随机推荐

  1. 简述在 MySQL 数据库中 MyISAM 和 InnoDB 的区别 ?

    MyISAM: 第 134 页 共 485 页不支持事务,但是每次查询都是原子的: 支持表级锁,即每次操作是对整个表加锁: 存储表的总行数: 一个 MYISAM 表有三个文件:索引文件.表结构文件.数 ...

  2. 手撕代码:leetcode70爬楼梯

    装载于:https://blog.csdn.net/qq_35091252/article/details/90576779 题目描述 假设你正在爬楼梯.需要n阶你才能到达楼顶. 每次你可以爬1或2个 ...

  3. Java中如何强制类型转换

    例如,当程序中需要将 double 型变量的值赋给一个 int 型变量,该如何实现呢? 显然,这种转换是不会自动进行的!因为 int 型的存储范围比 double 型的小.此时就需要通过强制类型转换来 ...

  4. synchronized 的作用?

    在 Java 中,synchronized 关键字是用来控制线程同步的,就是在多线程的环境 下,控制 synchronized 代码段不被多个线程同时执行. synchronized 既可以加在一段代 ...

  5. springboot使用自定义注解和反射实现一个简单的支付

    优点: 未使用if else,就算以后增加支付类型,也不用改动之前代码 只需要新写一个支付类,给添加自定义注解@Pay 首先: 定义自定义注解 Pay 定义 CMBPay ICBCPay 两种支付 根 ...

  6. 运筹学之"连通图"和"最小枝杈树"和"最短路线问题"

    一.连通图 必须每个点都有关系 图1 不算连通图 图2含有圈v1,v2,v5,可优化 图3就是所需的连通图 注意:图>连通图>树 二.最小枝杈树 获取是所有节点的最小值,只要是连通图就好, ...

  7. uniapp中生成二维码(附代码和插件)

    wxqrcode.js文件:  https://github.com/Clearlovesky/-js-jq-/tree/master/wxqrcode // 引入二维码库 import QR fro ...

  8. CVE-2022-22947 SpringCloud GateWay SpEL RCE

    CVE-2022-22947 SpringCloud GateWay SpEL RCE 目录 CVE-2022-22947 SpringCloud GateWay SpEL RCE 写在前面 环境准备 ...

  9. Static in C++

    Static in C++ static根据上下文会有两种含义,他们的区别如下 **在类class或者是在结构体struct 外 **使用static 类外的static修饰的符号在link阶段是局部 ...

  10. BootstrapBlazor-ValidateForm 表单验证组件

    原文链接:https://www.cnblogs.com/ysmc/p/16082279.html 故名思意,这个组件的作用我就不再多说了,配合 AutoGenerateColumnAttribute ...