pnpm
和 npm
之间有几个关键区别,主要体现在依赖管理、性能和存储机制上。以下是它们的一些主要区别:
1. 存储机制
-
npm: 每次安装依赖时,
npm
会在项目的node_modules
目录中安装所有指定的依赖,以及它们的所有子依赖。这可能导致很多重复的包被下载和存储。 -
pnpm: 使用了一种更加高效的存储机制,使用了全局存储(在
~/.pnpm-store
中)。当你安装一个依赖时,pnpm
只会将其安装一次,而所有使用该依赖的项目都会使用这个全局副本。pnpm
使用硬链接来将这些依赖链接到项目的node_modules
中,使得在多个项目之间节省了磁盘空间。
2. 依赖关系树
-
npm: 可能会创建一个嵌套的依赖结构,尤其是在不同版本的依赖之间存在冲突时。
递归依赖: 一个包可以依赖多个其他包,而这些包又可以依赖其他包,形成多层嵌套。
版本控制: 每个包可以指向特定版本的依赖,若不同包依赖同一包的不同版本,则会在树形结构中生成多个实例。
扁平化依赖: 随着 npm 的更新,npm 在一定程度上采用了扁平化的依赖结构,尽量减少深层嵌套,以避免因不同版本导致的冲突。
-
pnpm: 使用扁平化的依赖关系树,能更好地处理依赖冲突,从而提供更一致、更可预测的安装结果。
node_modules
中保持每个包自身的依赖,确保包之间的依赖不会冲突。- 不同版本的
package Z
会分别安装在不同的路径下,保持相互独立。- 如果所有包的依赖都使用同一版本,
pnpm
会尽量提升依赖,减少版本冗余,但在这种情况下,由于存在不同版本的依赖,因此各自独立存放。
3. 性能
-
npm: 通常在安装依赖时速度较慢,尤其是在重复安装相同的依赖时,这会导致必须下载打包存储在
node_modules
中的重复包。 -
pnpm: 由于使用了全局存储,
pnpm
在安装依赖时速度更快,特别是在多个项目之间共享相同依赖时,首次安装依赖后后续的安装将显著加速。
4. 硬链接
- pnpm: 使用硬链接将依赖链接到
node_modules
中,这样可以节省磁盘空间并加快安装速度。在多个项目中安装相同的包时,只需真实下载一次。
5. 工作区支持
-
npm: 在较新版本的 npm 中也开始支持工作区功能,但对于兄弟包之间的依赖管理较为简单。
-
pnpm: 原生支持工作区,使得在 monorepo项目的管理上更加灵活和高效。
构建工具和 CI/CD 集成
工作区支持CI/CD 环境的更轻松配置。从而可以在持续集成和交付过程中更高效地管理多个项目。
使用示例
在设置
pnpm
工作区时,你可以在你的项目根目录下创建一个pnpm-workspace.yaml
文件,然后列出工作区中包含的包的路径:packages: - 'packages/*' - 'libs/*'
然后,在工作区中,你可以使用命令如
pnpm install
来一次性安装所有包的依赖。
pnpm
的工作区功能为管理多个相关项目提供了一个高效且一致的方式,尤其是在大型项目或微服务架构中,极大地提升了开发和维护的便利性。