推荐使用 pnpm 而不是 npm

npm 的局限性

  1. 磁盘空间浪费

在 npm

早期版本中,每个项目的node_modules目录都会完整复制所有依赖包,即使多个项目依赖同一个包的相同版本,也会重复存储。这导致磁盘空间被大量占用,随着项目数量的增加,存储成本显著上升。虽然

npm v3

引入了扁平化结构,一定程度上减少了重复,但仍无法彻底解决问题。例如,在一个拥有多个项目的开发环境中,如果每个项目都依赖

lodash,那么每个项目的node_modules目录中都会有一份 lodash 的副本。

  1. 安装速度较慢

npm

安装依赖时,需要从远程仓库下载每个包并写入node_modules目录,对于大型项目,尤其是依赖众多的项目,这个过程涉及大量的

I/O 操作和网络请求,安装速度会受到明显影响。即使在 npm v5

之后支持了并行下载,在面对复杂的依赖树时,安装时间仍然较长。例如,当安装一个包含上百个依赖包的项目时,npm

可能需要数分钟甚至更长时间才能完成安装。 幽灵依赖问题 npm 的扁平化node_modules结构带来了 "幽灵依赖"

问题。项目可以访问未在package.json中声明的依赖包,这是因为依赖包的嵌套依赖可能被提升到node_modules的根目录,从而导致项目代码中能够直接引用这些未声明的依赖。这种不明确的依赖关系使得项目的依赖管理变得混乱,一旦依赖包的版本发生变化,可能会导致项目在运行时出现难以排查的错误。例如,项目

A 依赖包 B,而包 B 又依赖包 C,由于扁平化结构,包 C 可能会被提升到node_modules根目录,项目 A

的代码中就可以直接引用包 C,即使项目 A 的package.json中并没有声明对包 C 的依赖。

  1. pnpm 的优势

高效的磁盘空间管理 pnpm 使用内容寻址存储和符号链接 /

硬链接技术来管理依赖。所有依赖项都存储在全局共享存储中,当项目安装依赖时,pnpm

会通过硬链接将依赖包从全局存储链接到项目的node_modules目录,而不是复制整个包。这意味着,无论有多少个项目依赖同一个包的相同版本,磁盘上只会存储一份该包的文件。例如,假设有

100 个项目都依赖 lodash,在 pnpm 的管理下,lodash

在磁盘上只占用一份空间,大大节省了磁盘资源。而且,当依赖包的版本更新时,pnpm

只会将有差异的文件添加到存储中,进一步减少了磁盘空间的占用。 快速的安装速度 pnpm

的安装过程分为三个阶段:依赖解析、目录结构计算和链接依赖项。在依赖解析阶段,识别并获取仓库中没有的依赖;目录结构计算阶段,根据依赖关系计算node_modules目录结构;链接依赖项阶段,将以前安装过的依赖项从存储区直接链接到node_modules。这种方式避免了重复下载和复制文件,尤其是在处理大量依赖项时,安装速度明显快于

npm。在有缓存的情况下,或者安装已经存在于全局仓库中的包时,pnpm 的安装速度几乎可以达到 "秒级",极大地提高了开发效率。

清晰的依赖结构,杜绝幽灵依赖 pnpm 创建的是一个嵌套的、有严格依赖关系的node_modules结构。在 pnpm

的node_modules中,只会包含在package.json中明确声明的依赖。项目依赖的包所依赖的其他包,会被存放在node_modules/.pnpm/这个特殊目录里,并通过符号链接的方式链接到相应包的node_modules中。这就从根本上杜绝了

"幽灵依赖"

问题,确保项目的依赖关系清晰、可靠,不会出现意外引用未声明依赖的情况。在项目代码中尝试引用未在package.json中声明的依赖时,pnpm

会直接报错,保证了项目依赖的纯净性。 对 Monorepo 的良好支持 在处理 Monorepo(多包仓库)时,npm 的支持相对较弱,而

pnpm 原生支持

Monorepo,并且配置相对简单。通过在项目根目录创建pnpm-workspace.yaml文件并声明对应的工作区,就可以方便地管理多个包和项目。在一个包含多个前端项目和后端项目的

Monorepo 中,使用 pnpm 可以轻松实现依赖的共享和管理,减少重复安装,提高整个项目组的开发效率。

  1. 案例对比

磁盘空间占用对比 以一个实际的开发场景为例,有 5 个 React 项目,使用 npm 管理依赖时,这 5

个项目的node_modules目录总共占用了 8.7G 的磁盘空间;而使用 pnpm 后,同样的 5

个项目,node_modules相关的存储总共只占用了 3.2G,直接节省了 5G

左右的磁盘空间。对于磁盘空间有限的开发者来说,这无疑是一个非常有吸引力的优势。 安装速度对比 在安装一个具有复杂依赖树的项目时,使用 npm

执行npm install命令,等待时间长达数分钟;而使用 pnpm 执行pnpm

install,安装时间缩短了一半以上,极大地减少了开发过程中的等待时间,提高了开发节奏。 依赖管理稳定性对比 在一个团队协作项目中,由于

npm 的package-lock.json文件有时不能很好地锁定依赖版本,导致不同开发者安装的依赖版本不一致,经常出现

"在我电脑上能运行,在别人电脑上报错" 的情况。而切换到 pnpm

后,其pnpm-lock.yaml文件更严格地记录了依赖的版本、来源和包的哈希值,保证了不同开发者安装的依赖结构几乎 100%

一致,项目交接和协同开发变得更加顺畅,减少了因依赖不一致导致的问题。 综上所述,pnpm 在磁盘空间管理、安装速度、依赖结构的清晰性以及对

Monorepo 的支持等方面,都展现出了明显优于 npm 的特性。在当今前端项目日益复杂、依赖管理愈发重要的背景下,pnpm

为开发者提供了更高效、更可靠的包管理解决方案。

相关推荐
Darling噜啦啦1 分钟前
前端存储与 this 指向完全指南:从 LocalStorage 实战到 call/apply/bind 深度解析
前端·javascript
wei1986215 分钟前
.net添加web引用和添加服务引用有什么区别?
java·前端·.net
非科班Java出身GISer27 分钟前
ArcGIS JS API 5.0 ESM 双模块系统冲突解决方案
arcgis·arcgis js 引入问题·arcgis js amd·arcgis esm引入问题·arcgis js 资源冲突
格子软件1 小时前
2026年GEO优化系统源码级状态机与多模型调度拆解
java·前端·vue.js·人工智能·vue·geo
HUMHSX2 小时前
Vue 项目启动全流程解析:从入口文件到全局指令注册与页面渲染
前端·javascript·vue.js
有颜有货2 小时前
PMC生产排产的4种算法,一次讲清
java·服务器·前端
小虎牙0072 小时前
Android kotlin图片库Coil源码详解
android·前端
随风一样自由3 小时前
【前端领域】前端开发核心应用场景与落地实践
前端·前端框架
an317423 小时前
弹窗数据流设计的两种高阶架构实践
前端·vue.js·架构
谢尔登3 小时前
【React】 状态管理方案
前端·react.js·前端框架