摘要:带着好奇心,研究学习了一番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. 用 Java 写一个折半查找?

    折半查找,也称二分查找.二分搜索,是一种在有序数组中查找某一特定元素的搜索算法. 搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束:如果某一特定元素大于或者小于中间元素,则 ...

  2. 访问修饰符 public,private,protected,以及不写(默认) 时的区别?

    修饰符 当前类 同 包 子 类 其他包 public √ √ √ √ protecte d √ √ √ × default √ √ × × private √ × × × 类的成员不写访问修饰时默认为 ...

  3. Replicated State Machine和WAL

    在阅读raft论文的时候,考虑两个问题: 为什么要用Replicated State Machine?没有其他方式吗 为什么要先写日志再应用到Replicated State Machine,直接应用 ...

  4. 学习zabbix(四)

    一. 监控知识 1.硬件监控: 机房巡检,远程控制卡,IPMI 2.系统监控: cpu负载查看(指标):uptime(低于3),top(30%-70%), vmstat, mpstat 内存监控: f ...

  5. Linux中redis的redis.conf文件的移动

    Linux中启动redis的过程我想大家都会,但是正常使用redis包目录下启动redis时会出现以下页面: 那么此时只有按ctrl + c退出redis才能使用命令行输入别的命令,这种有点不方便. ...

  6. 领域驱动(DDD)设计和开发实战

    领域驱动设计(DDD)的中心内容是如何将业务领域概念映射到软件工件中.大部分关于此主题的著作和文章都以 Eric Evans 的书<领域驱动设计>为基础,主要从概念和设计的角度探讨领域建模 ...

  7. 无需Flash实现图片裁剪——HTML5中级进阶

    前言 图片裁剪上传,不仅是一个很贴合用户体验的功能,还能够统一特定图片尺寸,优化网站排版,一箭双雕. 需求就是那么简单,在浏览器里裁剪图片并上传到服务器. 我第一个想到的方法就是,将图片和裁剪参数(x ...

  8. 前端面试题整理——webpack相关考点

    webpack是开发工具,面试考点重点在配置和使用,原理理解不需要太深. 一.基本配置 1.拆分配置和merge 将公共配置跟dev和prod的配置拆分,然后通过webpack-merge对配置进行整 ...

  9. ES6-11学习笔记--Set

    Set:一种新的数据结构 常用方法 遍历 应用场景 WeakSet   常用方法: // Set的成员值一定是唯一的不重复的 let s = new Set([1, 2, 3, 2]) // 添加数据 ...

  10. JS中Map和ForEach的区别

    定义 forEach()方法: 针对每一个元素执行提供的函数. map()方法: 创建一个新的数组,其中每一个元素由调用数组中的每一个元素执行提供的函数得来. 区别 forEach()方法不会返回执行 ...