工程化-先进的包管理工具pnpm

260 阅读3分钟

背景

由于开发atom组件库,组件库包含多个package,package之间又会相互依赖。为了实现统一管理和依赖提升,需要使用Monorepo管理。 pnpm天生支持Monorepo,因此选择pnpm。

什么是pnpm

pnpm是一个包管理工具,英文叫做 performant npm,高性能的npm,其特点是节约磁盘空间并提升安装速度。

速度快

通过hard link机制,使得用户可以通过不同的路径引用方式去找到某个文件。pnpm 会在全局的store目录(.pnpm-store )里存储项目 node_modules 文件的 hard links 。

pnpm 对项目安装依赖的时候,如果某个依赖在 sotre 目录中存在,那么就会直接从store目录里面去hard-link,避免重复安装带来的时间消耗。当您安装包时会将其保存在全局存储中,然后从中创建一个硬链接,而不是进行复制。

节约磁盘空间

如果你用到了某依赖项的不同版本,那么只会将有差异的文件添加到仓库。所有文件都会存储在store中。 当软件包被安装时,包里的文件会硬链接到这一位置,而不会占用额外的磁盘空间。 这允许你跨项目地共享同一版本的依赖。

当使用 npm 安装依赖时,所有的依赖都会被提升到模块的根目录。 因此项目可以访问到未被添加进当前项目的依赖。

pnpm 使用软链的方式将项目的直接依赖添加进模块文件夹的根目录。

例如:

安装express,会在 node_modules 中形成这样两个目录:

node_modules/express/... 
node_modules/.pnpm/express@4.18.1/node_modules/...

node 正常寻找路径会去找的一个目录(node_modules/express),但是express里并没有node_modules,实际上这个文件只是个软连接。

它会形成一个到第二个目录(node_modules/.pnpm/express@4.18.1)的一个软连接,这样 node 在找路径的时候,最终会找到 .pnpm 这个目录下的内容。

第二个目录本身则是hard link,硬链接store中的位置

monorepo支持

pnpm 在 monorepo 场景可以说算得上是个完美的解决方案了,因为其本身的设计机制,可以轻松实现多package共享依赖。

兼容问题

pnpm 的主要问题在于 symlink(软链接)在一些场景下会存在兼容的问题,可能会在 windows 存在一些兼容的问题。

因为软连接而不能使用的场景:

  • Electron 应用无法使用 pnpm
  • 部署在 lambda 上的应用无法使用 pnpm

一些 node 基础库不支持 symlink 的情况导致使用 pnpm 无法正常工作。

总结

pnpm通过symlink(软链接)+hard link(硬链接)的方式提升了下载速度及磁盘空间利用效率。同时更好的支持了monorepo,可以使用在多package的项目中,因此atom组件库选择了pnpm进行包管理。

作者: moomo0