npm 直接将包安装到 node_modules
目录下,对于同一个依赖的不同版本会重复下载和存储,导致磁盘空间浪费和安装速度慢。
pnpm 使用了一种基于内容可寻址存储的机制,将所有下载的包存储在全局存储目录中(例如 ~/.pnpm-store
),并在项目的 node_modules
目录中使用硬链接或符号链接指向全局存储中的包。这种方式具有以下优点:
# 安装方式对比
npm: 直接复制包到项目目录 => 慢
pnpm: 硬链接/符号链接指向全局存储 => 快
npm 使用 package-lock.json
文件来记录依赖的版本信息,但在处理依赖树时效率较低,特别是在大型项目中,安装速度会明显变慢。
pnpm 采用一种更高效的方式来解析和锁定依赖关系,使用 pnpm-lock.yaml
文件来记录依赖信息。pnpm 的依赖解析算法优化了依赖树的生成和管理,使得在处理复杂依赖关系时更加快速和高效。
# 依赖解析对比
npm: 处理依赖树效率较低 => 慢
pnpm: 优化的依赖解析算法 => 快
npm 在安装包时虽然也支持并行下载,但其并行处理能力有限,导致在安装大量依赖时效率较低。
pnpm 在安装包时充分利用并行处理能力,最大化网络和磁盘 I/O 的利用率,从而显著提高安装速度。
# 并行处理对比
npm: 并行处理能力有限 => 较慢
pnpm: 充分利用并行处理 => 快
npm 在每次安装时需要重新从网络下载依赖,即使这些依赖已经在本地缓存中存在,也不会重复利用这些缓存。
pnpm 利用全局存储目录来缓存已经下载的包,确保在离线情况下也能高效地进行包安装。只要依赖已经存在于全局存储中,即使没有网络连接,也能快速完成安装。
# 缓存利用对比
npm: 不完全利用本地缓存 => 慢
pnpm: 全局缓存利用 => 快
npm 在不同项目中安装相同的依赖时,会多次下载和存储,导致磁盘空间的浪费。
pnpm 通过全局存储和硬链接机制,使得相同的依赖只需存储一次,大幅节省磁盘空间。
# 磁盘空间利用对比
npm: 重复存储相同依赖 => 浪费空间
pnpm: 全局存储和硬链接 => 节省空间
以下是一个简单的示例,展示如何使用 pnpm 和 npm 进行包安装:
npm install lodash
pnpm add lodash
安装 lodash
包时,pnpm 会将包存储在全局目录中,并在当前项目的 node_modules
中创建硬链接或符号链接。
pnpm 通过利用硬链接和符号链接、优化依赖解析、提高并行处理能力、充分利用离线缓存和全局存储机制,实现了显著的性能提升。相比于 npm,pnpm 在安装速度、磁盘空间利用和依赖管理方面都有明显优势。