pnpm
pnpm(performant npm) 通过软、硬链接(hark link、symbolic link) + 全局存储(store)结合的依赖管理方式完全实现了依赖树结构的包管理方式,解决了 npm3 及 yarn 中的幽灵依赖和 npm 分身的问题,提升了依赖包的安装速度,减小了磁盘空间占用。
pnpm 为何节省空间
它解决了 npm/yarn 平铺 node_modules 带来的依赖项重复的问题 (doppelgangers)
假设存在依赖依赖:
1 | . |
那么不可避免地在 npm 或者 yarn 中,lodash@3.0.0
会被多次安装,无疑造成了空间的浪费与诸多问题。
1 | ./node_modules/lodash |
这是一个较为常见的场景,在平时项目中有些库相同版本甚至会安装七八次,如 postcss
、ansi-styles
、ansi-regex
、braces
等,可以去yarn.lock/package-lock.json
中搜索一下。
而在 pnpm 中,它改变了 npm/yarn 的目录结构,采用软链接的方式,避免了 doppelgangers
问题更加节省空间。
它最终生成的 node_modules
如下所示,从中也可以看出它解决了幽灵依赖的问题。
1 | ./node_modules/package-a -> .pnpm/package-a@1.0.0/node_modules/package-a |
如此,依赖软链接的方式,可解决重复依赖安装 (doppelgangers) 的问题,如果一个项目占用 1000 MB,那么使用 pnpm 可能仅占用 800 MB
然而它除此之外,还有一个最大的好处,如果一个项目占用 1000 MB,传统方式十个项目占用 10000 MB,那么使用 pnpm 可能仅占用 3000 MB,而它得益于硬链接。
再借用以上示例,lodash@3.0.0
与 lodash@4.0.0
会生成一个指向全局目录(~/.pnpm-store
)的硬链接,如果新项目依赖二者,则可复用存储空间。
1 | ./node_modules/.pnpm/lodash@3.0.0/node_modules/lodash -> hardlink |
pnpm、yarn、npm 的区别
功能 | pnpm | yarn | npm |
---|---|---|---|
工作空间支持(monorepo) | O | O | O |
隔离的 node_modules | O-默认 | O | O |
提升的 node_modules | O | O | O-默认 |
自动安装 peers | O | X | O |
Plug’n’Play | O | O-默认 | X |
零安装 | X | O | X |
修补依赖项 | O | O | X |
管理 Node.js 版本 | O | X | X |
有锁文件 | O-pnpm-lock.yaml | O-yarn.lock | O-package-lock.json |
支持覆盖 | O | O-通过 resolutions | O |
内容可寻址存储 | O | X | X |
动态包执行 | O-通过 pnpm dlx | O-通过 yarn dlx | O-通过 npx |
Side-effects cache | O | X | X |
Listing License | O-Vua pnpm licenses list | O-Via a plugin | X |
安装和使用
1 | npm install -g pnpm |
1 | //设置源 |
查看依赖
1 | pnpm list 或(pnpm ls) |
运行脚本
1 | pnpm run xxx 或(pnpm xxx) |
包存储 store
pnpm store: pnpm 资源在磁盘上的存储空间
可以通过 pnpm store path
命令查看 store 存储目录的路径
在项目中执行pnpm install
的时候,依赖包存在于 store 中,直接创建依赖包硬链接到 store 中,如果不存在,则从远程下载后存储在 store 中,并从项目的 node_modules 依赖包中创建硬链接到 store 中。
pnpm store prune
,从存储中删除未引用的包。
workspce 协议
workspce:工作空间
workspace:*
协议,表示依赖的就一直是本地的包,而不是从npm registry
安装的包。
别名引用
假如工作区有一个名为 foo 的包,可以通过这样引用 "foo": "workspace:"
,如果是其它别名,可以这么引用:"bar": "workspace:foo@*"
。
相对引用
假如 packages 下有同层级的 foo、bar,其中 bar 依赖于 foo,则可以写作"bar": "workspace:../foo"
。
发布 workspace 包
当 workspace 包打包发布时,将会动态替换这些 workspace:依赖。
npm 或 Yarn 转 pnpm
操作步骤:
- 全局安装 pnpm
npm install -g pnpm
- 删除 npm 或 yarn 生成的 node_modules
1 | # 项目目录下运行或手动物理删除 |
- pnpm import 从其他软件包管理器的 lock 文件生成 pnpm-lock.yaml,再执行
pnpm install --frozen-lockfile
(相当于 npm ci)生成依赖,防止没有 lock 文件意外升级依赖包,导致项目出错
1 | # 生成`pnpm-lock.yaml` |
- 删除 npm 或 yarn 生成的 lock 文件
1 | # 删除 package-lock.json |
项目中的 npm 命令等修改为 pnpm,包括 README 文档、运行命令等