依赖管理结构
依赖管理结构
npm/yarn 的依赖管理结构
主要分为两个部分
-
- 将依赖包的版本区间解析为某个具体的版本号
-
- 下载对应版本依赖的
tar 包到本地离线镜像
- 下载对应版本依赖的
-
- 将依赖从离线镜像解压到本地缓存
-
- 将依赖从缓存拷贝到当前目录的
node_modules 目录
- 将依赖从缓存拷贝到当前目录的
然后,对应的包就会到达项目的
node_modules
└─ foo
├─ index.js
├─ package.json
└─ node_modules
└─ bar
├─ index.js
└─ package.json
如果
- 依赖层级太深,会导致文件路径过长的问题,尤其在
window 系统下。 - 大量重复的包被安装,文件体积超级大。比如跟
foo 同级目录下有一个baz ,两者都依赖于同一个版本的lodash ,那么lodash 分别在两者的node_modules 中被安装,也就是重复安装。 - 模块实例不能共享。比如
React 有一些内部变量,在两个不同包引入的React 不是同一个模块实例,因此无法共享内部变量,导致一些不可预知的bug 。
接着,从
node_modules
├─ foo
| ├─ index.js
| └─ package.json
└─ bar
├─ index.js
└─ package.json
所有的依赖都被拍平到
- 依赖结构的不确定性。
- 扁平化算法本身的复杂性很高,耗时较长。
- 项目中仍然可以非法访问没有声明过依赖的包
后面两个都好理解,那第一点中的不确定性是什么意思?这里来详细解释一下。假如现在项目依赖两个包

那么

取决于
尽管如此,
pnpm 依赖管理
▾ node_modules
▾ .pnpm
▸ accepts@1.3.7
▸ array-flatten@1.1.1
...
▾ express@4.17.1
▾ node_modules
▸ accepts -> ../accepts@1.3.7/node_modules/accepts
▸ array-flatten -> ../array-flatten@1.1.1/node_modules/array-flatten
...
▾ express
▸ lib
History.md
index.js
LICENSE
package.json
Readme.md
将包本身和依赖放在同一个
- 第一,你要知道
B 的版本是可能随时变化的,假如之前依赖的是C@1.0.1 ,现在发了新版,新版本的B 依赖 C@2.0.1,那么在项目A 当中npm/yarn install 之后,装上的是2.0.1 版本的C ,而A 当中用的还是C 当中旧版的API ,可能就直接报错了。 - 第二,如果
B 更新之后,可能不需要C 了,那么安装依赖的时候,C 都不会装到node_modules 里面,A 当中引用C 的代码直接报错。
还有一种情况,在