什么是pnpm

pnpm 的官方文档是这样介绍的:

Fast, disk space efficient package manager

因此,pnpm 本质上就是一个包管理器。且pnpm本身就代表了 performant npm 意味高性能npm,其特性为:

  • 包安装速度极快;
  • 磁盘空间利用非常高效。

基于npm开发的项目在开发过程中会越发臃肿且安装新的包会越发缓慢。其本质是即使是只引入了一个包的场景,但这个包背后所依赖于其他包,而其他包又依赖于某些包,同时这些依赖还带有版本的要求,npm必须满足所有安装包的依赖要求,并且在多个项目开发的过程中,如果有N个项目使用了相同的依赖,那么就会有N个包被存放于磁盘上。

那么,pnpm对此提出了两个解决方案:

  1. 如果你对同一依赖包需要使用不同的版本,则仅有 版本之间不同的文件会被存储起来。例如,如果某个依赖包包含 100 个文件,其发布了一个新 版本,并且新版本中只有一个文件有修改,则 pnpm update 只需要添加一个 新文件到存储中,而不会因为一个文件的修改而保存依赖包的 所有文件。
  2. 所有文件都保存在硬盘上的统一的位置。当安装软件包时, 其包含的所有文件都会硬链接自此位置,而不会占用 额外的硬盘空间。这让你可以在项目之间方便地共享相同版本的 依赖包。

最终结果就是以项目和依赖包的比例来看,你节省了大量的硬盘空间, 并且安装速度也大大提高了!对此,pnpm提供了一个更直观的可视化图体现了pnpm的核心思想:

PNPM
PNPM

示例:对于依赖极其复杂的hexo-theme-melody,npm花费了大量的时间进行依赖状态分析,并在最后报错安装失败

npm无法解决的安装
npm无法解决的安装

而pnpm直接安装完成,时间仅使用了2.5s

pnpm安装
pnpm安装

pnpm安装

若Windows系统之前还未配置Node.js环境,可以直接使用以下脚本进行安装:

1
iwr https://get.pnpm.io/install.ps1 -useb | iex

Linux系统为:

1
curl -fsSL "https://github.com/pnpm/pnpm/releases/latest/download/pnpm-linuxstatic-x64" -o /bin/pnpm; chmod +x /bin/pnpm;

若之前已有Node环境,则可以通过npm直接安装更好用的pnpm:

1
npm i -g pnpm

pnpm使用

与npm同样的是,将依赖项写入package.json文件,但不适用package-lock.json,而是使用pnpm-lock.yaml作为依赖解析文件

pnpm-lock.yaml
pnpm-lock.yaml

项目初始化命令

1
pnpm init

安装依赖

1
pnpm install XXX

运行package.json文件中定义的scripts脚本,启动服务

1
pnpm run xxx

更新依赖

1
pnpm update

删除依赖

1
pnpm remove

pnpm的node_modules目录实现

pnpm目录实现
pnpm目录实现

当使用 npm 或 Yarn Classic 安装依赖包时,所有软件包都将被提升到 node_modules 的 根目录下。其结果是,源码可以访问本不属于当前项目所设定的依赖包。

入图例所示,项目依赖了[email protected]版本,bar依赖了[email protected]版本,node_modules下只有直接依赖包[email protected]符号链接和.pnpm目录。Node.js解析时,[email protected]就会符号链接到实际位置.pnpm/[email protected]/node_modules/bar,包中的文件(并非包文件夹)都硬链接到.pnpm store中的对应文件,[email protected]做为bar的依赖,与bar的实际位置处于同一层级,符号链接指向实际位置.pnpm/[email protected]/node_modules/foo,包中的文件再硬链接至.pnpm store