Skip to content

前言

pnpm,全称是“performant npm”,意为“高性能的npm”, 是一个现代的 JavaScript 包管理工具,类似于 npm 和 Yarn,用来管理项目中的依赖包

优势

  1. 高效的磁盘利用 pnpm 采用了独特的硬链接(hard link)技术,把所有项目共用的依赖包存放在全局的缓存目录里,不同项目之间不会重复安装相同的包,节省磁盘空间。
  2. 快速安装 因为依赖共享在缓存,安装速度比传统的 npm 和 Yarn 更快,尤其是在多个项目都使用相同依赖时优势明显。
  3. 严格的依赖隔离 pnpm 默认用的是严格的节点模块结构,避免了“平滑依赖”问题,能帮你发现项目中缺失的依赖,减少“偶然能运行”的情况,提高代码的可维护性。
  4. 兼容 npm/Yarn pnpm 能安装 npm registry 上的包,且支持大多数 npm/yarn 的命令和配置,切换成本低。
  5. 支持工作区(monorepo) pnpm 原生支持 monorepo 项目结构,方便管理多个包的复杂项目。

为什么使用它

在使用它之前,先明白npm和yarn(特指yarn v1)到底有什么问题?

扁平化的node_modules 解决 “依赖地狱”问题 出现下面问题

1. “幽灵依赖”(Phantom Dependencies)」

举个例子:你的项目只安装了A包(npm install A)。但是A包自己依赖了B包。因为是扁平化结构,B包也会被提升到node_modules的根目录。

结果就是,你在你的代码里,明明没有在package.json里声明过B,但你却可以import B from 'B',而且代码还能正常运行!

这就是“幽灵依赖”。它像一个幽灵,让你的项目依赖关系变得混乱不堪。万一有一天,A包升级了,不再依赖B了,你的项目就会在某个意想不到的地方突然崩溃,而你甚至都不知道B是从哪来的。

「2. 磁盘空间的巨大浪费」

如果你电脑上有10个项目,这10个项目都依赖了lodash,那么在npm/yarn的模式下,你的磁盘上就会实实在在地存着**「10份」**一模一样的lodash代码。

「3. 安装速度的瓶颈」

虽然npm和yarn都有缓存机制,但在安装依赖时,它们仍然需要做大量的I/O操作,去复制、移动那些文件。当项目越来越大,node_modules动辄上G的时候,那个安装速度,真的让人等到心焦

符号链接

「1. 彻底告别“幽灵依赖”」

在pnpm的node_modules里,你只会看到你在package.json里**「明确声明」**的那些依赖。

你项目里依赖的A包,它自己所依赖的B包,会被存放在node_modules/.pnpm/这个特殊的目录里,然后通过 「符号链接(Symbolic Link)」 的方式,链接到A包的node_modules里。

这意味着,在你的项目代码里,你根本访问不到B包。你想import B?对不起,直接报错。这就从结构上保证了,你的项目依赖关系是绝对可靠和纯净的。

「2. 磁盘空间的“终极节约”」

pnpm会在你的电脑上创建一个“全局内容可寻址存储区”(content-addressable store),通常在用户主目录下的.pnpm-store里。

你电脑上所有项目的所有依赖,「都只会在这个全局仓库里,实实在在地只存一份」

当你的项目需要lodash时,pnpm不会去复制一份lodash到你的node_modules里,而是通过 「硬链接(Hard Link)」 的方式,从全局仓库链接一份过来。硬链接几乎不占用磁盘空间。

这意味着,就算你有100个项目都用了lodash,它在你的硬盘上也只占一份的空间。这个特性,对于磁盘空间紧张的同学来说,简直是福音。

「3. 极速的安装体验」

因为大部分依赖都是通过“链接”的方式实现的,而不是“复制”,所以pnpm在安装依赖时,大大减少了磁盘I/O操作。

它的安装速度,尤其是在有缓存的情况下,或者在安装一个已经存在于全局仓库里的包时,几乎是“秒级”的。这种“飞一般”的感觉,一旦体验过,就再也回不去了。