谁才是前端最强包管理器?

173 阅读6分钟

前言

在我们前端开发中,包管理器是每个人一定会使用到的,可以帮助我们更好的管理项目中的这个包。在目前主流开发中,常见的包管理工具就三种:npm、yarn、pnpm,那么今天我们来好好聊聊这三者性能的差异吧。

永远的老大哥npm

npm(node package manager)由node.js官方推出的包管理工具。在这三个包管理器中,绝大数人最先用的大概率就是npm。

由于npm是由node官方推出的,自然npm可以很好的和node的所有版本适配。在npm中也是拥有很大数量的开源包,我们想要的工具基本上都能从npm库里面找到。由于有着大量开发者在npm里面创作维护,npm也有着很好的稳定性,即使是老古董传到今天还是可以正常启动。

说完了npm的优点,缺点自然是有的。

在使用npm的过程中,首先最容易感受到的就是慢!!!

为什么会出现很慢的情况?那就是因为npm默认官方源在国外,所有我们在国内因为网络原因就会限制。因此,有了tnpm。

tnpm实际上和npm差别不大,主要区别就是使用的淘宝镜像源。这极大的加快了我们国内开发者下载速度。

聊完了npm的下载问题。在我们每次使用npm的时候,它都会重新下一份项目依赖,但是像有些依赖是好几个独立项目都需要的。那么我们重复下好几次依赖是不是会有点浪费内存?所有,这也是npm存在着的一个大问题。

npm管理依赖的方式并不严格,开发者要是在不同环境下协作开发,可能会出现依赖版本不一致的情况。npm还有一个幽灵依赖的大问题,我们留到后面再说。

后起之秀yarn

yarn是由Facebook开发出来的,它就是因为npm存在的问题进而优化所创作的。接下来我们从多方面来和npm对比

yarn下载速度会比npm快,因为yarn采用并行安装的技术大大提高了安装速度,而且yarn还支持本地缓存技术,对于已经安装过的依赖,再次安装的时候可以从缓存中获取,极大的提高了效率。

前面提到npm管理依赖并不严格,而yarn它会记录下每个包的版本信息,能够保证不同环境下依赖的一致性,这样就可以统一开发。

yarn也有自己的特色创新。首先yarn支持离线下载,只要之前安装过依赖包在本地缓存中存在,在没网的情况下也可以下载依赖。其次,yarn支持Monorepo结构(单一代码块,即所有代码都放在一个库里),这对要管理多个有管理的包是非常方便的。多个包放在同一个仓库里,统一了管理,也减少了重复依赖的安装。

虽然这样听起来yarn完胜npm,但是yarn还是有很多缺点的。

yarn相对于npm没有那么广泛的社区群体,要是碰到什么问题就有点孤立无援。而且yarn可能会过于依赖缓存。如果缓存出现了什么bug的话,就会 导致安装出现问题,当后续开发出现问题的话,这可能是毁灭性的,找起bug会有点困难。yarn的配置比npm复杂些,要是我们开发一个小型项目的话,yarn的有些高级功能未免有点杀猪用牛刀。

未来之星pnpm

pnpm是一个比较新的包管理工具,由Zoltan Kochan发起的一个开源项目,目前由其核心团队维护并得到了社区的广泛支持。那么,我们来分析分析pnpm为什么大受欢迎吧。

pnpm的安装速度比yarn和npm都快,当需要处理有着复杂依赖的项目时,pnpm的威力就能真正感受到。pnpm通过缓存和共享依赖的方式,避免了重复下载,提高了效率。

pnpm很好的节省了磁盘空间,它使用硬链接和去重机制,把依赖包安装在全局位置上,多个项目共享这些依赖,节省了磁盘空间。

pnpm管理依赖严格,强制依赖嵌套结构让项目的依赖关系更加清晰明确。而pnpm也支持Monorepo。pnpm因为有着清晰的依赖关系,管理起来也更加方便。

说了这么多pnpm的优点,pnpm并非万能的。pnpm并不能完全和npm,yarn兼容。并且pnpm在2017年6月发布,社区规模发展并没有特别大,但是还是有着很好的未来前景的,期待着pnpm未来的茁壮成长。

目前,我们已经基本上对比完这三个包管理工具。在我们开发的时候,可能会出现一种情况---幽灵依赖。使用npm,yarn可能会出现,pnpm解决了这个问题。

什么叫做幽灵依赖呢?

在我们的Vue/React项目里使用npm install下载依赖,我们会发现node_modules里面有很多依赖,但是我们在package.json里面却没有声明却下载过来了。这种没有申明却下载的依赖就是幽灵依赖,这种原因是因为可能一个库里依赖了另一个库。

在我们开发的时候会使用到很多包,包和包之间会形成一些依赖关系。在最初npm使用的是文件结构,文件结构是一种树形结构。当结构不匹配时,就会重复下载依赖下来。

后面yarn解决了这个问题,yarn把所有依赖都拍扁平了。如果说 A 依赖了 B 和 C,那么 A 里边的代码在 require 或者是 import 的时候,在本身的目录里找不到这两个依赖,就会向上查找,向上找就找到了。

image.png 这样子做是不会嵌套了,但是会产生幽灵依赖,本来我们手动安装了 A,但是依赖 B C 依旧会安装进来。

那么我们了解了问题产生的原因,现在我们就陷入了一个两难的情况,要么就接收重复文件,这样子就没有幽灵依赖了,要么就得接受幽灵依赖,无法两者兼得。然而pnpm很好的解决了幽灵依赖。

pnpm不像 npm和yarn那样把所有依赖都“扁平化”到顶层的node_modules。pnpm会在项目的node_modules下为每个包建立一个“虚拟隔离环境”,每个包只能访问自己package.json里声明的依赖。pnpm在node_modules里用符号链接指向全局store里的真实包内容,并且只为声明的依赖建立链接。

Ending

以上内容就是对npm、yarn、pnpm三个包管理器的对比,我们应该根据自己项目的特点来选择最合适的包管理器方便我们开发。就我个人而言,目前最喜欢的还是比较简单npm包管理器。