注册
web

为什么需要PNPM ?


PNPM是什么?


在日常工作里面,总是有同事让我将npm替换成pnpm,理由是这玩意速度更快,效率更高。那到底pnpm是什么呢?他为什么比npm/yarn有着更大的优势?
首先,毫不疑问,pnpm是作为一个前端包管理器工具被提出的,作者的初衷是为了能够开发出一款能够有效节省磁盘空间,提高安装速度的包管理工具。
其次,npm和yarn存在的诸多问题,也让开发者诟病已久,pnpm也是在这样的背景下被开发出来并广受欢迎的。
image.png
image.png
image.png


PNPM解决了什么样的问题?


在讨论pnpm解决了什么样的问题之前,我们可以先看看npm和yarn这些传统包管理工具到底存在什么样的问题。


NPM 2


在Npm2.x里面,当你观察node_modules时,你会发现对于不同包之间的依赖关系,npm2.x采用的是层层嵌套的方式去管理这些依赖包。
image.png
对于依赖关系来说,嵌套的管理方式虽然让不同包之间的依赖关系一目了然,但是却存在着诸多的问题。



  • 公共的依赖无法重复利用。不同的包里难免会存在相同的依赖,但是在npm2.x里面,这些公共依赖会被复制很多次,存在于不同的包的嵌套node_modules里,这样会导致下载速度的下降以及浪费了许多磁盘空间。
  • **嵌套关系过深时,路径名过长。**在window下,有很多程序无法处理超过260个字符的文件路径名,如果嵌套关系过深时,就有可能会超出这个限制,导致windows下存在无法解析的现象。


NPM 3 & YARN


针对上述Npm 2存在的两个典型的问题,Yarn和Npm3采用了扁平化的依赖管理方式,所有的依赖不再层层嵌套,而是全部都在同一层,这样就同时解决了重复依赖多次复制和路径名过长的问题了。
image.png
可以看到使用npm3安装的express使,大部分的包都不会有二层的node_modules的,当然,如果同时存在多个版本的包时,则还是会出现部分嵌套node_modules的情况。
另外,Yarn和Npm 3都采用了lock文件,借此来保证每次拉取同一个项目的依赖时,使用的是同一个版本,避免不同版本之间的差异性导致的项目Bug。
但是,问题又来了,难道使用了扁平化的依赖管理方式就是完美的吗,这种管理方式会不会产生新的问题?答案否定的,扁平化的管理方式会导致两个最主要的问题



  • 幽灵依赖
  • 磁盘空间问题没有完全解决

幽灵依赖


幽灵依赖是指你的项目明明没有在package.json文件里声明的依赖,但是在代码里面却可以使用到。导致这个问题的最主要的原因就是,依赖扁平化了,当你的项目寻找依赖的时候,可以找到所有node_modules里的最外层依赖。
显然,幽灵依赖是会带来隐患的,当你依赖的包A有一天不再需要包B了, 你对B的幽灵依赖就会导致错误,从而发生问题。


磁盘问题


当同一个项目依赖了某个包的多个版本时,Npm3和Yarn只会提升其中的一个,而其余版本的包还是不能避免复制多次的问题 。


PNPM是如何解决这些问题的?


在讨论Pnpm的机制之前,我们需要先学习下一些操作系统相关的知识。


链接


链接实际上是一种文件共享的方式。在Linux的文件系统中,除了文件名和文件内容,还有一个很重要的概念,就是inode,inode类似于C语言的指针,它指向了物理硬盘的一个区块,只有有文件指向这个区块,他就不会从硬盘中消失。而硬链接和软连接最大的区别,则是inode的与原文件的关系。


硬链接


一般来说,inode与文件名、文件数据是一对一的关系,但我们可以通过shell命令让多个文件名指向同一个inode,这种就是硬链接(hard link)。由于硬链接文件和源文件使用同一个inode,并指向同一块文件数据,除文件名之外的所有信息都是一样的。所以这两个文件是等价的,可以说是互为硬链接文件。修改任意一个文件,可以看到另外一个文件的内容也会同步变化。
也正是因为有多个相同的inode指向同一个区块,所以硬链接的源文件即使被删除,也不会对链接文件有任何影响。


软链接


软连接又称符号链接,与硬链接共用一个inode不同的是,软链接会创建一个新的inode,存放着源文件的绝对路径信息,并指向源文件。当用户访问软链接时,系统会自动将其替换为该软链接所指向的源文件的文件路径,然后访问源文件。
而PNPM则是利用了以上链接的机制,来解决Npm和Yarn存在的问题。
当你使用Pnpm安装依赖时,Pnpm会在全局的仓库里保存一份npm包的内容,然后再利用链接的方式,从全局仓库里链接到你项目里的虚拟仓库,也就是node_modules里的是.pnpm。


image.png


你所安装的依赖,都会单独存放在node_modules下,而依赖所依赖的npm包都会通过软链接的方式,链接.pnpm里的虚拟仓库里的包,而.pnpm里的包,则是通过硬链接从全局Store里链接过来的。
image.pngimage.png
通过软硬链接结合的方式,Pnpm可以很有效的解决了Npm和yarn遗留的问题:
1、抛弃了扁平化的管理方式,避免了幽灵依赖。
2、Npm包的存储方式都是放在全局,使用到的时候只会建立一个硬链接,硬链接和源文件共享同一份内存空间,不会造成重复依赖的空间浪费。另外,当依赖了同一个包的不同版本时,只对变更的文件进行更新,不需要重复下载没有变更的部分。
3、下载速度,当存在已经使用过的npm包时,只会建立链接,而不会重新下载,大大提升包安装的速度。


PNPM天生支持Monorepo?


monorepo 是在一个项目中管理多个包的项目组织形式。
它能解决很多问题:工程化配置重复、link 麻烦、执行命令麻烦、版本更新麻烦等。
而利用Pnpm的workSpace配合changesets,就可以很简单的完成一个Monorepo项目的搭建,所以说Pnpm天生就是Mo

作者:Gamble_
来源:juejin.cn/post/7240662396020916282
norepo的利器。

0 个评论

要回复文章请先登录注册