【翻译】NPM install算法

本文详细介绍了npm在安装package时遵循的算法,包括从磁盘读取依赖树、克隆并添加新依赖、处理版本冲突及避免无限递归。通过具体示例说明了如何决定依赖的层级,并解释了为何npm不允许在当前文件夹安装同名package以防止循环引用导致的无限安装。同时,文章还定义了元数据的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文档:https://docs.npmjs.com/cli/install#algorithm

安装一个package,npm遵循以下算法:

从磁盘读取已存在的node_modules依赖树(以下简称为依赖树)

克隆以上获取的依赖树

读取package.json以及各元数据​​​​​​​,将其添加到克隆的依赖树上

遍历克隆的依赖树,添加没有的依赖,遵循以下两条原则:

尽可能靠近树的根部添加依赖

不破坏其他modules

对比原始树,定制出一系列将原始树变为克隆树的操作

执行操作,最深层的(目录)优先处理

操作包括安装、更新、移除和移动

以 package{dep} 这种形式举个例子: A{B,C}, B{C}, C{D},会生成如下目录结构:

A
+-- B
+-- C
+-- D

其中,因为A已安装了C,所以B所依赖的C提升了一个层级。D也在最高层级,是因为它不和其他产生冲突。

再看一个例子:A{B,C}, B{C,D@1}, C{D@2},这将生成如下目录结构:

A
+-- B
+-- C
   `-- D@2
+-- D@1

由于B所依赖的D@1版本将被安装在最顶层,C必须将D@2版本安装在其下目录中。这种算法是有确定性的,但不同命令安装两个依赖(D@1和D@2)会生成不同的树。

查看npm-folders获取更多npm生成详细文件结构的信息。

限制

npm不会在当前文件夹下安装任何与文件夹同名的package。可以用--force忽略这个限制,但更常见的是重命名本地package。

这样做会有些少见的不合理的极限例子——循环引用会导致npm安装package进行无限安装。下面是最简单的例子:

A -> B -> A' -> B' -> A -> B -> A' -> B' -> A -> ...

A是某版本的package,A‘ 是同一个package不同的版本。由于忽略限制,B不能依赖已安装好的A,必须再单独拷贝一份A。同样的道理,之后的A’ 必须安装B‘。然后又因为B‘ 依赖于A,即便A已经在顶层安装,但已被忽略,循环就进入了无限递归。

为了避免以上情形,npm不允许安装任何和依赖树上已存在的祖先节点同名的包。这样虽然更准确,但是也更复杂,已存在的版本需要被链到新的需要引用的地方。

名词解释

元数据(Metadata)

​​​​​​​元数据是关于数据的数据,在某些时候不特指某个单独的数据,可以理解为是一组用来描述数据的信息组/数据组,该信息组/数据组中的一切数据、信息,都描述/反映了某个数据的某方面特征,则该信息组/数据组可称为一个元数据。

元数据可以为数据说明其元素或属性(名称、大小、数据类型等),或其结构(长度、字段、数据列),或其相关数据(位于何处、如何联系、拥有者)。

容易混淆概念:数据元(Data element)

又称数据类型,通过定义、标识、表示以及允许值等一系列属性描述的数据单元。在特定的语义环境中被认为是不可再分的最小数据单元。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值