当前位置:网站首页>运行npm install命令的时候会发生什么?
运行npm install命令的时候会发生什么?
2022-04-22 18:33:00 【华为云开发者社区】
本文分享自华为云社区《运行npm install命令的时候会发生什么?》,作者: gentle_zhou。
npm(node package manager),是随同Node.js一起安装的第三方包管理器;通过npm,我们可以安装、共享、分发代码,管理项目的依赖关系。
我们日常在下载第三方依赖的时候,都会用到一个命令npm install,然后依赖包就会被安装到node_modules目录下;但是我们在运行这个命令的时候,都会发生什么呢?带着好奇心,我去调研学习了一番。
大致的流程是:npm install命令输入 > 检查node_modules目录下是否存在指定的依赖 > 如果已经存在则不必重新安装 > 若不存在,继续下面的步骤 > 向 registry(本地电脑的.npmrc文件里有对应的配置地址)查询模块压缩包的网址 > 下载压缩包,存放到根目录里的.npm目录里 > 解压压缩包到当前项目的node_modules目录中。

(上面的图片就显示了项目中依赖如果过多的尴尬:等待时间过长,下载下来依赖过多导致node_modules过大)
下面会介绍一下npm处理依赖的早前和当前的方式 以及 几种不同的install命令下载方式。
早期版本:递归
在npm早期版本里,npm处理依赖的方式很粗暴简单。它会严格按照根目录下package.json文件的结构以及各个子依赖包的package.json文件的结构,递归地把依赖安装到它们各自的node_modules目录里。这样如果是个小项目,只需要几个依赖且这些依赖不会依赖别的依赖,那么这样的树形结构就还算清晰明了(node_modules的结构与package.json里的结构一一对应且层级结构明显)。
但如果我们的项目是个大项目,里面的依赖非常多(导致嵌套层级非常深),且不同的层级可能会引用同一个依赖(导致重复冗余),就不是我们想要的情形了。
当前版本:扁平化
于是,为了解决以上递归管理依赖带来的问题,npm在 3.X版本里做了一次更新,引入了扁平化管理(dedupe)的方式。dedupe是dedeplicated的缩写,即duplicates were remove,把重复的移除。
扁平化管理的思路就是首先遍历package.json文件下dependencies和devDependencies字段里的依赖,作为依赖树的根节点;然后在每个根节点依赖下面都会有其依赖的依赖,作为其子节点;npm会开启多进程从每个根节点开始逐步往下寻找更深层次的节点。而package.json文件下dependencies和devDependencies字段里的依赖会被安装在node_modules根目录下。在遍历这些依赖的时候,如果发现有重复的依赖模块(重复:模块名相同且semantic version兼容;这里的兼容,是指语义化版本都会有一段版本允许范围,如果两个依赖的版本号是在这个范围交际里就说明是兼容;比如依赖X依赖于依赖Y@^1.0.0,而依赖Z依赖于依赖Y@^1.1.0,则Y@^1.1.0就是兼容版本),就直接将其丢弃。
但是如果仅仅这样,其实也有风险。在大项目中,很有可能会碰到依赖A依赖于依赖C-1.0版本,依赖B依赖于依赖C-2.0版本;而在执行npm install命令的时候,会按照package.json里面的依赖顺序依次解析,因此依赖C-1.0和依赖C-2.0的在文件里的放置顺序会导致Node_modules的依赖结构产生变化。而且为了让开发者可以使用最新的依赖包,package.json文件里通常只会锁定大版本(即文件里依赖如果是^1.1.0版本,npm就会去仓库中获取符合1.x.x形式的最新版本),因此某些依赖包小版本更新后,也会造成依赖结构的改变。所以,为了解决npm install命令导致的这种不确定问题,npm 5.x版本里还新增了package-lock.json文件。
package-lock.json文件可以保证每次执行npm install后生成的node_modules目录结构一定是完全相同的。下图就是package-lock.json中其中一个依赖的信息,有name-包名,version-包的版本号,dependencies-和node_modules中包结构一一对应的对象,resolved-包具体的安装来源,integrity-包的hash值,requires-对应子依赖的依赖:

注:并不是所有的子依赖都有dependencies这个属性,只有子依赖的依赖和当前已安装在根目录的Node_modules中的依赖起了冲突之后,才会有这个属性。
置于为何说package-lock.json 文件 和 node_modules 目录结构是一一对应的。还是举刚刚前面提及的那个依赖冲突导致依赖结构产生变化的例子,“依赖A依赖于依赖C-1.0版本,依赖B依赖于依赖C-2.0版本”,此时因为package-lock.json文件的存在,我们会把依赖C-1.0版本安装在依赖A的node_modules目录下(对应依赖A在package.json文件里的dependencies属性),依赖C-2.0版本安装在根目录下。这可以保障每次安装生成的依赖目录结构保持相同。
package-lock.json 文件还有个优点,就是它会缓存每个包的具体版本和下载链接,在后期再去install的时候,就不需要再去远程仓库进行查询操作了,减少了大量网络请求。
几种不同的install命令下载方式
- npm install xxx #(XXX是某依赖包)安装依赖模块至项目node_modules目录下,不会修改package.json文件里的内容
- npm install -g xxx #安装依赖模块到全局(而不是项目node_modules目录下),不会将该依赖模块写到package.json文件里的
dependencies和devDependencies字段里 - npm install --save xxx #安装依赖模块到项目node_modules目录下,并将依赖写入到package.json文件里的
dependencies字段中;该依赖是开发和生产环境里都需要的 - npm install --save-dev xxx #安装依赖模块到项目node_modules目录下,并将依赖写入到package.json文件里的
devDependencies字段中
版权声明
本文为[华为云开发者社区]所创,转载请带上原文链接,感谢
https://huaweicloud.blog.csdn.net/article/details/124344932
边栏推荐
- Hackmyvm (XXV) helium, series of articles continuously updated
- mysql 之 MHA
- One click download scheme of serial port of esp32 / esp8266 series single chip microcomputer without peripheral circuit
- 接口协议之抓包分析 TCP 协议
- [fundamentals of interface testing] Chapter 9 | detailed explanation of postman global variables and environment variables
- redis发布订阅
- 在 Kubernetes 集群中部署现代应用的通用模式
- 【electron】文件下载卡住
- Chapter 119 SQL function right
- 大话测试数据(二):概念测试数据的获取
猜你喜欢

Leetcode 111: minimum depth of binary tree
![[drive] TX2 transplants EC20 startup module](/img/f1/5ef4a9bc5deb84523dc935719b9dea.png)
[drive] TX2 transplants EC20 startup module

leetcode-470. 用 Rand7() 实现 Rand10()

Dynamic programming: multiple knapsack problem

Transformation operator

Chapter 119 SQL function right

关于.net core 中使用ActionFilter 以及ActionFilter的自动事务

SegAttnGAN Text to Image Generation with Segmentation Attention

我为什么不再使用 flomo 了

Why don't I use flomo anymore
随机推荐
SegAttnGAN Text to Image Generation with Segmentation Attention
电脑上怎么快速切换显示不同的软件界面
反射:newInstance()根据包名加类名得到具体类对象接口,调用指定类中的方法.
Research Report on the development of asset management and custody banking industry in 2021
膨胀卷积论文笔记
大话JMeter4|不同的并发数可以自动化做压测吗?
Leetcode 108: convert an ordered array into a binary search tree
Read and write txt files in C language
How to select the mobile phone running memory?
Chapter 119 SQL function right
Secyun assisted the "SaaS cloud management platform solution based on pseudo application integration framework" released by CETC 32
【服务器数据恢复】服务器进水导致多块硬盘同时掉线,服务器崩溃的数据恢复案例
Codeforces Round #784 (Div. 4) AK题解
WiFi Technology Overview: WiFi things
This API hub is powerful. It contains open APIs such as nailing enterprise wechat, and can be debugged directly!
【驱动】TX2移植EC20启动模块
k8s 部署Redis集群
C# 从list 或者string中随机获取一个
B树[概念]
第119章 SQL函数 RIGHT