Hello,大家好,我是 Sunday
包管理工具是前端开发中的重要一环,但是现在前端的包管理工具有很多。很多新同学很难搞清这么多不同的包管理工具之间的差异,所以说,咱们今天就针对 npm、yarn、pnpm、cnpm 来进行下统一的介绍,帮大家梳理清楚这些包管理工具的区别!
npm:当之无愧的老大哥
说起前端的包管理工具,就不得不提 npm ——全称 Node Package Manager,是 Node.js 官方自带的包管理器,也是前端构建工具链的基础之一。
npm 最初诞生于 2010 年,当时随着 Node.js 的流行而快速崛起,它解决了 JavaScript 社区长期以来的代码共享难题 —— 你不再需要手动复制粘贴 JS 代码片段,而是可以直接通过一个命令安装和管理第三方模块。
在那个前端还靠一手 jQuery 打天下的年代,npm 在当年绝对是一种全新的概念。
npm 包含了如下核心功能:
- 依赖安装:npm install 一键安装项目所需模块
- 版本管理:通过 package.json 和 package-lock.json 管理依赖版本
- 模块发布:可将自己的代码发布到 npm 仓库(registry),供他人使用
- 脚本系统:支持 npm run 执行构建、测试等命令,成为项目自动化的入口
只不过,最为最初的包管理工具,npm 一开始(当然也包括现在)也存在非常多的问题,比如说:安装慢、node_modules 过大、依赖库版本锁定不一致 等等的问题。
虽然,npm 在 v5 之后,进行了大量的优化,但是很多问题依然存在。比如,很多同学都问过我的这个报错(使用 cnpm 安装即可解决):
图片
同时也是因为这些问题,所以才出现了后续的 yarn、pnpm、cnpm 等
yarn:为解决 npm 的问题而来
2016 年,Facebook 等大厂联合推出了一个全新的包管理器 —— Yarn,它的诞生不是为了颠覆什么,而是为了解决当时 npm 的诸多“痛点”。
在那个 npm install 慢如蜗牛、依赖版本时常出错的年代,Yarn 就像是完成了一次大的技术升级,把整个包管理的流程都做了优化。
- yarn.lock 文件:引入了自己的锁文件(区别于 npm 的 package-lock.json),更早解决了依赖版本不一致的问题
- 更快的安装体验:Yarn 通过缓存机制和并行安装方式,大大提升了安装速度。装过一次的包,下次无需重新拉。
- 离线安装:这是一个非常实用的特性,即使断网,你也可以依赖缓存离线安装项目,适合对网络依赖敏感的开发场景。
- 原子化安装:安装失败会自动回滚,防止项目进入“半安装”状态。
目前,Yarn 的最新版本为 V2 代号:Berry(2020 年 1 月发布),在这个版本中 Yarn 将架构进行了重新,提供了一个叫做 Plug'n'Play (PnP) 的概念。这种方式会 跳过 node_modules,依赖通过 .pnp.cjs 文件直接映射,但是对于已经习惯了 node_modules 的前端开发者来说,就有点不太友好了。
pnpm:解决硬盘空间不足的问题
我们项目中所有的包都会被安装到 node_modules 中,这就导致 node_modules 会变得非常大!有多大呢?大家可以看下自己项目中的 node_modules 大小,你会发现它的体积可能会比你的代码体积大了 100 倍以上。当时还出现了一个这样的表情图:
因此,pnpm 就出现了。其核心就是为了解决 node_modules 占用硬盘空间过大的问题
pnpm 通过一种“硬链接 + 内容寻址”的存储方式,将所有依赖包统一下载到全局缓存中(.pnpm-store),每个项目的 node_modules 并不真的“安装”包,而是使用软链接指向缓存中的真实文件,同一个包只会下载、存储一份,再多个项目共用。
这样就带来了巨多好处,比如:下载速度飞快,空间占用大幅度下降,并且还可以完美兼容现有生态(保留 node_modules)。
并且,针对 Monorepo 架构,pnpm 也提供了非常好的支持(应该可以说是支持最好的包管理器了)
cnpm:国内的淘宝镜像
cnpm 和前面所有的包管理工具不太一样,严格来说 cnpm 不应该被叫做包管理工具,而应该被叫做一个 cli 工具。
因为,npm 的官方源服务器在国外,所以,我们在使用 npm install 时常常遇到下载失败的问题。
那么为了解决下载失败的问题,阿里巴巴就维护了一套 npm 的镜像源,每间隔几分钟就会自动同步 npm 的数据,从而保证数据与 npm 一直,就好像是 npm 的镜子一样。那么在我们就可以直接从国内阿里的镜像源来安装依赖了。
所以,cnpm 的正确的概念应该是 cnpm = npm 的国内镜像 + 一套 CLI 工具。