🧑💻 npm vs pnpm:为什么从 npm 切换到 pnpm?
1. pnpm 提供更快的安装速度
传统 npm 安装包的方式:
npm在每个项目中都会单独下载并安装依赖,每个依赖都会有一个完整的副本,这会造成很多重复的安装。
pnpm 的优势:
- pnpm 使用全局存储 :它将所有依赖包存在一个全局目录中(通常是
~/.pnpm-store),然后通过硬链接(hard link)将这些依赖连接到你项目的node_modules中。这样就避免了重复的依赖下载和存储。
结果:
- 安装依赖速度更快,节省磁盘空间。
- 同样的依赖只会下载一次,多个项目间共享相同的依赖。
实际效果: 在很多情况下,pnpm 的安装速度比 npm 快 2-3 倍,尤其是多个项目使用相同依赖时。
2. 更高效的磁盘空间使用
npm 的磁盘问题:
- 使用
npm安装依赖时,每个项目的node_modules中都会有完整的包副本,甚至是多个版本的包。这对于大项目或多个项目而言,占用的磁盘空间非常巨大。
pnpm 的磁盘优化:
pnpm采用 硬链接 的方式,所有的包都存储在一个全局目录中,而项目只保存链接。这样,多个项目可以共享相同的包副本,避免重复存储,提高磁盘空间利用率。
结果:
- 节省了大量的磁盘空间,尤其是在多项目开发时。
3. 严格的依赖管理
npm 的依赖管理问题:
npm允许直接在node_modules中安装未在package.json中声明的依赖(所谓的 "hoisting"),这会导致项目中出现隐式依赖,可能在开发时看不出来,但在生产环境中可能会引发问题。
pnpm 的依赖管理优势:
pnpm强制 严格的模块解析 ,它会将依赖安装在项目的node_modules/.pnpm中,并且只会链接项目中显式声明的依赖。这可以避免不必要的隐式依赖问题。
结果:
- 依赖关系更清晰,避免"恶意"隐式依赖。
- 适用于大规模项目,可以更好地控制依赖版本,避免意外冲突。
4. 提升的工作流和 CI/CD 性能
传统的 npm 在 CI/CD 中的劣势:
- 在持续集成(CI)和持续交付(CD)过程中,
npm会重新安装所有依赖,这会消耗大量时间,尤其是当依赖非常多时。
pnpm 的优势:
pnpm的 全局存储和缓存 机制使得 CI/CD 流程更加高效。它可以快速找到并复用已安装的依赖,减少重复下载和安装,从而显著缩短 CI/CD 流程时间。
结果:
- 更快的持续集成和交付。
- 缩短部署时间,提升开发和部署效率。
5. 自动管理锁文件
npm 锁文件的问题:
- 在早期版本的 npm 中,
package-lock.json存在不同的 npm 版本之间的兼容性问题,导致相同的依赖版本在不同机器上可能会有不同的解析结果。
pnpm 的优势:
pnpm的 lockfile 通过pnpm-lock.yaml完全解决了这个问题,确保无论在哪台机器上安装,依赖解析都是一致的,并且 优化了多个版本的支持。
6. 支持 monorepo 项目
npm 的 monorepo 支持不足:
- 虽然
npm最近开始提供一些 monorepo 的支持(通过npm workspaces),但它的支持仍然不如pnpm完善。
pnpm 的 monorepo 支持:
pnpm天生支持 monorepo(多仓库管理),提供 更快速的工作空间(workspaces)支持,允许你轻松管理多个子项目,且不会在磁盘上占用过多空间。
结果:
- 如果你的项目是 monorepo 项目 ,使用
pnpm会显得更加高效和简洁。
📈 总结:pnpm 的优势
- 更快的依赖安装速度:因为 pnpm 使用全局存储和硬链接,避免了重复下载,节省时间和空间。
- 更低的磁盘占用:多个项目共享依赖,避免了冗余的包存储。
- 更严格的依赖管理:减少隐式依赖的风险,确保依赖关系更加清晰。
- 更高效的 CI/CD 性能:加速持续集成和部署流程,避免重复安装。
- 更好地支持 monorepo:非常适合多项目仓库。
🚀 是否值得切换到 pnpm?
如果你正在开发一个 中到大型的 Vue3、React 或其他前端项目 ,或者你的项目是 monorepo ,我强烈建议你切换到 pnpm,你将体验到:
- 更快的依赖安装
- 更清晰的依赖管理
- 更高效的 CI/CD 流程
在日常开发中,如果项目规模逐渐增大,pnpm 的优势会更加明显。
🎯 如何切换到 pnpm?
如果你决定切换到 pnpm,只需要:
-
安装 pnpm:
npm install -g pnpm -
删除原有的
node_modules和package-lock.json:bashrm -rf node_modules package-lock.json -
使用 pnpm 安装依赖:
pnpm install
就这么简单!之后你就可以使用 pnpm run dev 来启动开发环境了。