前端安装包中的幽灵依赖
文章类型:node
发布者:hp
发布时间:2024-11-25
在项目开发过程中,软件包可以依赖别的包,由此就产生了依赖图,
由于历史原因,nodeJs和npm采用不同的方式,
NPM使用真实软件包的文件夹副本来作为图的顶点,用子文件夹关系来表示图的边
NodeJs添加了一个特殊的解析规则,其效果就是引入额外的图边,也就是指向所有父文件夹的子文件夹
我们把这些没有在包的依赖中声明的定义,称为“幽灵依赖”
幽灵依赖:是指在项目中使用了一些,没有被定义在其package.json文件中的包
{
"name": "my-library",
"version": "1.0.0",
"main": "lib/index.js",
"dependencies": {
"minimatch": "^3.0.4"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
- my-monorepo/
- package.json
- node_modules/
- semver/
- ...
- my-library/
- package.json
- lib/
- index.js
- node_modules/
- brace-expansion
- minimatch
- ...
NPM采取的方案
1:每个项目都有自己的「node_modules 树」,树中包含了大量的包文件夹副本。
2:NPM 2.x,node_modules 文件夹树 很深 且 重复度高,但将 幽灵依赖 控制到了最少。
3:NPM 3.x 引入的安装算法会打平整个树,消除了大量的重复依赖,代价是引入了更多的 幽灵依赖 (额外的图边)
4:已安装的 「node_modules 树」不是独一无二的的。
1:不兼容的版本
2:丢失依赖问题
采用pnpm安装包,把所有的包。存到一个仓库文件夹里面,然后在node_modules里面用正常的树结构,来表达包依赖
1:pnpm使用符号链接Symbolic link(软链接)来创建依赖项的嵌套结构,将项目的直接依赖符号链接到node_modules的根目录,直接依赖的实际位置在.pnpm/<name>@<version>/node_modules/<name>,依赖包中的每个文件再硬链接(Hard link)到.pnpm store。
2:.pnpm称为虚拟存储目录,以平铺的形式储存着所有的项目依赖包,每个依赖包都可以通过.pnpm/@/node_modules/路径找到实际位置。