一文读懂:pnpm是什么?它和npm的区别?如何安装和使用pnpm?

一、pnpm 是什么

pnpm(Performant npm)和 npm(Node.js Package Manager)是两种不同的JavaScript包管理工具,它们在多个方面存在显著的差异。

以下是它们之间的主要区别:

二、pnpm 和 npm 的区别

1.包的存储方式

  • npm:npm将每个包都下载到项目的node_modules目录中。这意味着,如果多个项目使用相同的包版本,它们会在各自的node_modules目录下存储独立的副本。
  • pnpm:pnpm使用一个全局的存储库(store)来存储所有已下载的包,并在每个项目中创建符号链接(或硬链接)指向这些包。这种方式避免了在多个项目中重复存储相同的依赖项,从而节省了磁盘空间。

2.空间占用

  • npm:由于每个项目都存储了独立的包副本,因此空间占用相对较大。
  • pnpm:通过共享存储库和符号链接的方式,pnpm显著减少了空间占用。

3.安装速度

  • npm:由于每个项目都需要下载并安装其所需的依赖项,安装速度可能会受到网络速度、包大小等因素的影响。
  • pnpm:由于pnpm使用全局存储库并通过符号链接引用包,因此安装速度通常更快。特别是在处理大量依赖项或需要频繁安装依赖项的项目中,pnpm的优势更为明显。

4.依赖解析和node_modules结构

  • npm:npm的依赖解析策略可能会导致依赖项被扁平化到顶层node_modules目录,这可能会引入版本冲突或意外的行为。
  • pnpm:pnpm采用严格的依赖解析策略,并创建非扁平化的node_modules结构。这减少了意外覆盖依赖的风险,并避免了由于包之间的版本冲突所导致的问题。

5.命令行接口(CLI)

npm 和 pnpm 的命令行接口非常相似,大多数常用命令(如install、run、test等)都是一致的。然而,在某些高级功能和命令上,它们之间可能存在差异。

6.兼容性

  • npm:作为最早和最广泛使用的包管理器,npm几乎被所有的Node.js项目所支持。
  • pnpm:虽然pnpm在许多项目中能够无缝工作,但在某些依赖于特定node_modules结构的工具或项目中可能会遇到兼容性问题。

7.其他功能

pnpm 还提供了一些额外的功能,如作为Node.js版本管理器(类似于nvm等工具)、支持多平台(Windows、Linux、macOS)等。

8.总结

npm和pnpm在包的存储方式、空间占用、安装速度、依赖解析和node_modules结构、命令行接口以及兼容性等方面存在显著的差异。
选择哪一个工具主要取决于个人或团队的需求以及项目的特定要求。

对于需要节省磁盘空间、提高安装速度并减少依赖冲突的项目,pnpm可能是一个更好的选择。
然而,在兼容性方面,npm可能具有更广泛的支持。

三、如何安装和使用 pnpm

1.安装pnpm

如果你还没有安装nodejs,请先看这篇,传送门:《Windows系统安装nodejs版本管理工具nvm(node version manager)实现nodejs版本自由切换详细教程踩坑实录》

效果:

D:\AI\AnythinLLM\frontend>npm install -g pnpm

added 1 package in 8s
npm notice
npm notice New major version of npm available! 10.7.0 -> 11.1.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.1.0
npm notice To update run: npm install -g npm@11.1.0
npm notice

2.验证安装

安装完成后,可以使用 pnpm -vpnpm -version,来验证 pnpm 是否安装成功:

D:\AI\AnythinLLM\frontend>pnpm -v
10.4.1

D:\AI\AnythinLLM\frontend>pnpm -version
10.4.1

若看到上面的版本号,则大功告成!

3.配置 npm(可选)

如果你需要配置 pnpm 的镜像源(例如使用国内镜像源加速),可以运行以下命令:

pnpm add -g pnpm@latest
pnpm config set registry http://registry.npmmirror.com

都看到这里了,各位帅哥/美女,不管有用没用,都帮忙点个赞呗,❤️谢谢~


Author
吴所畏惧 2025.02.20
<think>嗯,用户问为什么用npm安装依赖时会出现安装不全的问题,而pnpm却可以解决。我需要先理解两者的依赖管理机制差异。 首先,回想一下npm的工作原理。npm安装依赖时,采用的是扁平化的node_modules结构。也就是说,所有的依赖包会被提升到顶层目录,尽可能避免重复安装。但这样做可能导致不同版本的包被错误地共享,特别是当多个包依赖同一个库的不同版本时。如果某个版本被提升到顶层,而其他版本被嵌套在各自的目录里,可能会导致某些依赖找不到正确版本,从而安装不全或者出现版本冲突。 然后是pnpmpnpm使用的是内容寻址存储硬链接的方式。每个依赖包都存储在全局的存储目录中,项目中的node_modules通过硬链接指向这些文件。同时,pnpmnode_modules结构保持了依赖树的严格性,每个包只能访问自己明确声明的依赖,避免了幽灵依赖的问题。这样即使多个包依赖不同版本,也能各自正确链接到对应的版本,不会遗漏或冲突。 需要进一步验证的是,npm的扁平化结构确实会导致某些情况下依赖被错误地覆盖或遗漏,而pnpm的严格结构确保了每个依赖都被正确安装。例如,当两个包依赖同一个库的不同版本,npm可能会只安装其中一个版本到顶层,另一个版本则嵌套在子目录中,如果某些情况下模块解析逻辑出错,嵌套的版本可能无法被正确找到,导致安装不全。而pnpm通过符号链接严格的依赖树,确保每个包都能访问到正确的版本,不会遗漏。 另外,pnpm的依赖解析算法可能更高效,能精确处理版本冲突,确保所有依赖都被正确安装。而npm在早期版本中确实存在依赖提升导致的问题,虽然后来有所改进,但某些边缘情况可能仍然存在。 总结起来,npm的扁平化结构虽然减少了冗余,但带来了潜在版本冲突依赖不全的风险;pnpm通过硬链接严格结构,既节省空间又保证了依赖的完整性正确性。需要确保解释清晰,对比两者的机制,并举例说明可能的问题场景,让用户更容易理解。</think>### 为什么 npm 安装依赖可能不全,而 pnpm 可以解决? #### 1. **npm 的依赖管理机制** - **扁平化结构(但非严格)** npm 从 v3 开始采用 `扁平化(flat)` 的 `node_modules` 结构。如果多个依赖包需要同一个次级依赖(例如 `lodash@^4.0.0`),npm 会尝试将其提升到顶层目录,避免重复安装。 - **问题场景**: 假设包 A 依赖 `lodash@^4.0.0`,包 B 依赖 `lodash@^3.0.0`。npm 可能将 `lodash@4.0.0` 提升到顶层,而 `lodash@3.0.0` 被嵌套在包 B 的目录下。如果包 B 的代码中未明确声明对 `lodash@3.0.0` 的路径引用,可能导致运行时错误。 - **依赖冲突与提升规则** npm 的依赖提升策略可能导致某些次级依赖未被正确解析,尤其是当多个版本冲突时,部分依赖可能被“隐藏”在嵌套目录中,而模块系统无法正确找到它们。 --- #### 2. **pnpm 的核心优势** - **基于内容寻址的存储** pnpm 将所有依赖包存储在全局的 `content-addressable store` 中。项目中的 `node_modules` 通过硬链接(hard link)指向这些文件,**节省磁盘空间且避免重复下载**。 - **严格的依赖结构** pnpm 的 `node_modules` 保持严格的树形结构,每个包只能访问其直接声明的依赖。例如: ``` node_modules ├── A -> .pnpm/A@1.0.0/node_modules/A └── .pnpm └── A@1.0.0 └── node_modules ├── A └── lodash@4.0.0 # 硬链接到全局存储 ``` - **关键点**:每个包的依赖会被严格隔离,确保版本一致性。 - **符号链接与精准解析** pnpm 使用符号链接(symlink)精准映射依赖关系,避免版本冲突。即使多个包依赖同一库的不同版本,也能各自独立引用。 --- #### 3. **典型问题对比** | 场景 | npm 的表现 | pnpm 的表现 | |-----------------------|-------------------------------------|---------------------------------------| | **依赖多版本冲突** | 可能提升错误版本,导致依赖缺失 | 每个版本独立存储,严格隔离 | | **幽灵依赖** | 允许访问未声明的提升依赖 | 仅允许访问显式声明的依赖 | | **磁盘空间占用** | 可能重复安装相同版本(未优化存储) | 通过硬链接复用文件,大幅节省空间 | --- #### 4. **总结原因** - **npm 的缺陷**:依赖提升策略扁平化结构可能导致版本覆盖、依赖路径解析错误,尤其是在复杂依赖图中容易丢失部分次级依赖。 - **pnpm 的改进**: 1. 通过硬链接全局存储避免冗余。 2. 严格的依赖隔离确保每个包都能访问到声明的准确版本。 3. 符号链接机制保证模块解析的可靠性。 因此,pnpm 的架构设计从根本上解决了 npm 因依赖提升扁平化结构导致的“安装不全”问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吳所畏惧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值