pnpm也称高性能npm,相比npm、yarn优势在于节省磁盘空间并提升安装速度
安装
在 POSIX 类系统上,即使尚未安装 Node.js,也可以使用以下脚本安装 pnpm:
curl -fsSL https://get.pnpm.io/install.sh | sh -
// 如果没有安装 curl,可以使用 wget
wget -qO- https://get.pnpm.io/install.sh | sh -
这里解释下POSIX,即可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ),简单理解为一个标准,遵循该标准的系统首先就是Unix和Linux,其中苹果的操作系统也是Unix-based同样遵循该标准
在 Windows 系统上(PowerShell):
iwr https://get.pnpm.io/install.ps1 -useb | iex
使用 npm
npm install -g pnpm
常用命令
命令 | 解释 |
---|---|
pnpm -v | 查看已安装的pnpm的版本 |
pnpm install xxx/pnpm i xxx | 安装依赖 |
pnpm run xxx | 运行package.json中scripts脚本 |
pnpm config get registry | 查看源 |
pnpm config set registry <淘宝源或私服> | 切换源 |
pnpm add xxx | 安装依赖包到 dependencies |
pnpm add -D xxx | 安装依赖包到devDependencies |
pnpm update xxx/pnpm up xxx | 更新依赖包 |
pnpm remove xxx | 删除依赖包 |
实现原理
pnpm结合软硬链接与新的依赖组织方式,大大提升了包管理的效率,同时解决了幽灵依赖问题
在分析该原理图前首先我们先了解一些操作系统的知识以及幽灵依赖
- 硬链接 - hard link
就是一个文件的一个或多个文件名。再说白点,所谓链接无非是把文件名和计算机文件系统使用的节点号链接起来。因此我们可以用多个文件名与同一个文件进行链接,这些文件名可以在同一目录或不同目录-百度百科
通过硬链接,不会产生额外的磁盘占用,并且,两个文件都能找到相同的磁盘内容
文件A与文件B有相同引用,通过硬链接,不会产生额外的磁盘占用,修改文件A,文件B也同时改变
- 软链接 - Symbolic links/Soft links
软链接又叫符号链接,这个文件包含了另一个文件的路径名。可以是任意文件或目录,可以链接不同文件系统的文件。-百度百科
如果为某个文件或文件夹A创建符号连接B,则B指向A
- 幽灵依赖
即某个包没有被安装在package.json里,但是用户却能够引用到这个包,原因是在npmv3版本以后,一个库只要被其他库依赖,哪怕没有显式声明在package.json中,会被安装在node_modules的一级目录里
pnpm官网提供的原理图:
- node_modules 下安装包结构为树形,避免了幽灵依赖,同时以软链接方式将内容指向 node_modules/.pnpm目录下具体文件
- .pnpm 目录以打平结构管理每个版本包的源码内容,以硬链接方式指向 pnpm-store 中的文件地址,所有依赖包都安装在全局目录 ~/.pnpm-store/v3/
npm/pnpm目录对比
使用npm安装antd后目录结构:
npm init
npm install antd
npm安装的包在node_modules目录下被打平
使用pnpm安装antd后目录结构:
pnpm init
pnpm install antd
pnpm安装的包在node_modules目录下只有package.json中安装的依赖包以及.pnpm,依赖包通过软链方式指向.pnpm目录里的文件
查看pnpm store全局存储目录的路径
pnpm store path
npm/yarn项目转pnpm
删除node_modules
rm -rf node_modules
基于项目中lock文件生成pnpm-lock.yaml
pnpm import
安装依赖
pnpm install --frozen-lockfile
--frozen-lockfile相当于npm ci生成依赖,防止没有lock文件意外升级依赖包
总结
pnpm
依赖文件通过三次寻址方式找到下载资源
第一次通过package.json
中安装依赖找到node_modules
目录下依赖包,即node_modules/antd
;
第二次通过node_modules/antd
软链接 node_modules/.pnpm/antd@4.23.1/node_modules/antd
解决了代码重复引用的问题;
第三次通过node_modules/.pnpm/antd@4.23.1/node_modules/antd
硬链接 ~/.pnpm-store/v3/files/00/xxx
已经脱离当前项目路径,指向一个全局统一管理路径,这种方式符合 node_modules 默认寻址方式,节省了磁盘空间,也解决了幽灵依赖