- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
相信小伙伴们都接触过 npm/yarn ,这两种包管理工具想必是大家工作中用的最多的包管理工具, npm 作为 node 官方的包管理工具,它是随着node的诞生一起出现在大家的视野中,而 yarn 的出现则是为了解决 npm 带来的诸多问题,虽然 yarn 提高了依赖包的安装速度与使用体验,但它依旧没有解决 npm 的依赖重复安装等致命问题。 pnpm 的出现完美解决了依赖包重复安装的问题,并且实现了 yarn 带来的所有优秀体验,所以说 pnpm才是前端工程化项目的未来 .
如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,文章公众号首发,关注 前端南玖 第一时间获取最新文章~ 。
在npm@3之前, node_modules 结构可以说是 整洁 、 可预测 的,因为当时的依赖结构是这样的:
node_modules
└─ 依赖A
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖B
├─ index.js
└─ package.json
└─ 依赖C
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖B
├─ index.js
└─ package.json
每个依赖下面都维护着自己的 node_modules ,这样看起来确实非常整洁,但同时也带来一些较为严重的问题:
从上面的依赖结构我们可以看出,依赖A与依赖C同时引用了依赖B,此时的依赖B会被下载两次。此刻我们想想要是某一个依赖被引用了n次,那么它就需要被下载n次。(此时心里是不是在想,怎么会有如此坑的设计) 。
我们再来看另外一种依赖结构:
node_modules
└─ 依赖A
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖B
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖C
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖D
├─ index.js
└─ package.json
这种依赖层级少还能接受,要是依赖层级多了,这样一层一层嵌套下去,就像一个依赖地狱,不利于维护.
为了解决上述问题, npm3 与 yarn 都选择了扁平化结构,也就是说现在我们看到的 node_modules 里面的结构不再有依赖嵌套了,都是如下依赖结构:
node_modules
└─ 依赖A
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖C
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖B
├─ index.js
├─ package.json
└─ node_modules
node_modules 下所有的依赖都会平铺到同一层级。由于require寻找包的机制,如果A和C都依赖了B,那么A和C在自己的node_modules中未找到依赖C的时候会向上寻找,并最终在与他们同级的node_modules中找到依赖包C。 这样 就不会出现重复下载的情况。而且依赖层级嵌套也不会太深。因为没有重复的下载,所有的A和C都会寻找并依赖于同一个B包。自然也就解决了实例无法共享数据的问题 。
由于这个扁平化结构的特点,想必大家都遇到了这样的体验,自己明明就只安装了一个依赖包,打开 node_modules 文件夹一看,里面却有一大堆.
这种扁平化结构虽然是解决了之前的嵌套问题,但同时也带来了另外一些问题:
这个怎么理解,为什么会产生这种问题呢?我们来仔细想想,加入有如下一种依赖结构:
A包与B包同时依赖了C包的不同版本, 由于同一目录下不能出现两个同名文件,所以这种情况下同一层级只能存在一个版本的包,另外一个版本还是要被嵌套依赖.
那么问题又来了,既然是要一个扁平化一个嵌套,那么这时候是如何确定哪一个扁平化哪一个嵌套的呢?
这两种结构都有可能,准确点说 哪个版本的包被提升,取决于包的安装顺序! 。
这就是为什么会产生依赖结构的 不确定 问题,也是 lock 文件 诞生的原因,无论是 package-lock.json (npm 5.x 才出现)还是 yarn.lock ,都是为了保证 install 之后都产生确定的 node_modules 结构.
尽管如此,npm/yarn 本身还是存在 扁平化算法复杂 和 package 非法访问 的问题,影响性能和安全.
前面说了那么多的 npm 与 yarn 的缺点,现在再来看看pnpm是如何解决这些尴尬问题的.
快速的,节省磁盘空间的包管理工具 。
就这么简单,说白了它跟 npm 与 yarn 没有区别,都是包管理工具。但它的独特之处在于:
从上图可以看出, pnpm 的包安装速度明显快于其它包管理工具。那么它为什么会比其它包管理工具快呢?
我们来可以来看一下各自的安装流程 。
resolving:首先他们会解析依赖树,决定要fetch哪些安装包.
fetching:安装去fetch依赖的tar包。这个阶段可以同时下载多个,来增加速度.
wrting:然后解压包,根据文件构建出真正的依赖树,这个阶段需要大量文件IO操作.
上图是pnpm的安装流程,可以看到针对每个包的三个流程都是平行的,所以速度会快很多。当然pnpm会多一个阶段,就是通过链接组织起真正的依赖树目录结构.
pnpm 内部使用 基于内容寻址 的文件系统来存储磁盘上所有的文件,这个文件系统出色的地方在于
hardlink
。 hardlink
,仅仅写入那 一个新增的文件
。 pnpm 与 npm/yarn 另外一个很大的不同就是支持了 monorepo,pnpm内置了对monorepo的支持,只需在工作空间的根目录创建pnpm-workspace.yaml和.npmrc配置文件,同时还支持多种配置,相比较lerna和yarn workspace,pnpm解决monorepo的同时,也解决了传统方案引入的问题.
monorepo 的宗旨就是用一个 git 仓库来管理多个子项目,所有的子项目都存放在根目录的 packages 目录下,那么一个子项目就代表一个 package .
pnpm使用的是npm version 2.x类似的嵌套结构,同时使用.pnpm 以平铺的形式储存着所有的包。然后使用Store + Links和文件资源进行关联。简单说pnpm把会包下载到一个公共目录,如果某个依赖在 sotre 目录中存在了话,那么就会直接从 store 目录里面去 hard-link,避免了二次安装带来的时间消耗,如果依赖在 store 目录里面不存在的话,就会去下载一次。通过Store + hard link的方式,使得项目中不存在NPM依赖地狱问题,从而完美解决了npm3+和yarn中的包重复问题.
我们分别用 npm 与 pnpm 来安装vite对比看一下 。
npm | pnpm |
---|---|
所有依赖包平铺在 node_modules 目录,包括直接依赖包以及其他次级依赖包 |
node_modules 目录下只有 .pnpm 和直接依赖包,没有其他次级依赖包 |
没有符号链接(软链接) | 直接依赖包的后面有符号链接(软链接)的标识 |
pnpm安装的 vite 所有的依赖都软链至了 node_modules/.pnpm/ 中的对应目录。 把 vite 的依赖放置在同一级别避免了循环的软链.
pnpm 是通过 hardlink 在全局里面搞个 store 目录来存储 node_modules 依赖里面的 hard link 地址,然后在引用依赖的时候则是通过 symlink 去找到对应虚拟磁盘目录下(.pnpm 目录)的依赖地址.
这两者结合在一起工作之后,假如有一个项目依赖了 A@1.0.0 和 B@1.0.0 ,那么最后的 node_modules 结构呈现出来的依赖结构可能会是这样的
node_modules
└── A // symlink to .pnpm/A@1.0.0/node_modules/A
└── B // symlink to .pnpm/B@1.0.0/node_modules/B
└── .pnpm
├── A@1.0.0
│ └── node_modules
│ └── A -> <store>/A
│ ├── index.js
│ └── package.json
└── B@1.0.0
└── node_modules
└── B -> <store>/B
├── index.js
└── package.json
node_modules 中的 A 和 B 两个目录会软连接到 .pnpm 这个目录下的真实依赖中,而这些真实依赖则是通过 hard link 存储到全局的 store 目录中.
pnpm 下载的依赖全部都存储到 store 中去了, store 是 pnpm 在硬盘上的公共存储空间.
pnpm 的 store 在Mac/linux中默认会设置到 {home dir}>/.pnpm-store/v3 ;windows下会设置到当前盘符的根目录下。使用名为 .pnpm-store的文件夹名称.
项目中所有 .pnpm/依赖名@版本号/node_modules/ 下的软连接都会连接到 pnpm 的 store 中去.
原文首发地址 点这里 ,欢迎大家关注公众号 「前端南玖」 ,如果你想进前端交流群一起学习, 请点这里 。
我是南玖,我们下期见!!! 。
最后此篇关于pnpm才是前端工程化项目的未来的文章就讲到这里了,如果你想了解更多关于pnpm才是前端工程化项目的未来的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一名优秀的程序员,十分优秀!