跳到主要内容

pnpm

相较于npmyarnpnpm通过其独特的依赖管理模式解决了两大长期困扰着开发者的问题:幽灵依赖NPM分身,除此之外还在依赖的安装速度上得到了大幅的提升。

在详细介绍pnpm实现原理之前,让我们先聚焦一下上文所提到的问题是指怎样的场景。

幽灵依赖(Phantom dependencies)

无论是npm还是yarn,为了尽量减少重复模块的安装都采用了扁平化的node_modules设计。即使我们的项目中只安装一个模块,最终在node_modules中还是会看到成百上千的子模块,首先这种观感体验不佳,寻找某个指定模块时非常麻烦,更重要的是我们的源代码中可以直接引用这些子模块来使用,这是个很不好的哲学,当后续高版本的父模块不再依赖这些子模块时,我们就需要调整代码来适应这些变化,在大型项目中碰到这种情况还是很麻烦的。

npm分身(npm doppelgängers)

npmyarn的扁平化的设计是为了减少重复的模块,但是并不能完全避免,我们还会碰到这种情况(即npm 分身)。

如当我们已经安装了A@1.0时,如果依赖的模块B和模块C都依赖于A@2.0,此时只能分别在模块B和模块C的node_modules下安装A@2.0,因此难免造成体积的增大。

pnpm的依赖管理

为了介绍pnpm的原理,最简单的方式就是我们创建一个新项目来看看实际的效果,通过pnpm i安装模块时,会发现node_modules中存在两个文件夹,分别是.pnpm和模块A,模块A实际上是一个符号连接(软连接)指向着.pnpm/A.pnpm中是各种子模块。这样我们的代码中就无法直接引用这些子模块了,并且整个node_modules结构更加清晰了,从而解决了幽灵依赖的问题

.pnpm中的文件,本质上是一个硬链接,当我们通过pnpm安装某个模块时,会首先安装在~/.pnpm-store/v3下,然后创建在项目的node_modules/.pnpm中创建一个硬链接,因此不管怎样同一个版本的某个包我们总是只会安装一次,后续需要时不需下载直接生成硬链接即可,从而解决了NPM分身的问题

由此可以看出,pnpm不仅解决了上述的两大棘手问题,带来了更加简洁的node_modules,只要全局中已经安装了某个模块,后续在某个项目中安装时无需下载,直接创建硬链接即可,大大减少下载时长。

命令

pnpm link --global
pnpm link --global <name>