都2022年了,pnpm还不快到碗里来

pnpm是一个新兴的包管理工具,以其快速的安装速度和磁盘空间效率受到关注。文章探讨了npm、yarn存在的问题,如幽灵依赖和NPM分身,并介绍了pnpm的网状+平铺的node_modules结构如何解决这些问题。通过使用hard link和symbolic link,pnpm实现了性能提升,减少了文件下载数量。此外,文章还详细阐述了pnpm的store、links、peerDependencies、workspace等功能,以及与npm、yarn的区别,并提供了常用命令的使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pnpm是一款当代备受关注的 新兴(问题较多) 包管理工具,使用过的同学们都会被它极快的安装速度、极少的磁盘存储空间所吸引!

首先,为什么会出现pnpm?作者一开始对yarn的发布有很高的期待,但是发布后并没有满足作者的一些期待,反而让作者有些失望。

After a few days, I realized that Yarn is just a small improvement over npm. Although it makes installations faster and it has some nice new features, it uses the same flat node_modules structure that npm does (since version 3). And flattened dependency trees come with a bunch of issues
几天后,我意识到 Yarn 只是对 npm 的一个小小的改进。尽管它使安装速度更快,并且具有一些不错的新功能,但它使用与npm相同的平面node_modules结构(自版本 3 起)。扁平化的依赖树带来了一系列问题(具体后面会讲)

至于为什么叫pnpm?是因为pnpm作者对现有的包管理工具,尤其是npmyarn的性能特别失望,所以起名叫做perfomance npm,即pnpm(高性能npm)

如何突显pnpm的性能优势?在pnpm官网上,提供了一个benchmarks图表,它比对了项目在npm、pnpm、yarn(正常版本和PnP版)中,installupdate场景下的耗时:

image.png

下面表格是上图中的具体数据:

action cache lockfile node_modules npm pnpm Yarn Yarn PnP
install 1m 12.2s 15.7s 22.1s 27.5s
install 1.6s 1.3s 2.6s n/a
install 9.5s 4s 8.6s 1.9s
install 14.2s 7.9s 14.2s 7.4s
install 25.4s 13s 15.3s 21.1s
install 2.1s 1.8s 8.3s n/a
install 1.6s 1.4s 9.4s n/a
install 2.1s 5.9s 15s n/a
update n/a n/a n/a 1.6s 12.1s 18.7s 32.4s

可以看到pnpm(橘色)有很明显性能提升,在我们项目实践中(基于gitlib)提升更明显cache-pathsstore dir搭配使用后)

在讨论性能提升原因之前,我们需要先了解下现有包管理工具中node_modules存在的问题

node_modules 安装方式

目前有两种安装方式:`Nested installation`、`Flat installation`

Nested installation 嵌套安装

npm@3 之前,node_modules结构是干净可预测的,因为node_modules 中的每个依赖项都有自己的node_modules文件夹,在package.json中指定了所有依赖项。例如下面所示,项目依赖了foofoo又依赖了bar,依赖关系如下图所示:

node_modules
└─ foo
   ├─ index.js
   ├─ package.json
   └─ node_modules
      └─ bar
         ├─ index.js
         └─ package.json

上面结构有两个严重的问题:

  • package中经常创建太深的依赖树,这会导致 Windows 上的目录路径过长问题

  • 当一个package在不同的依赖项中需要时,它会被多次复制粘贴并生成多份文件

Flat installation 扁平安装

为了解决上述问题,npm 重新考虑了node_modules结构并提出了扁平化结构。在npm@3+yarn中,node_modules 结构变成如下所示:

node_modules
├─ foo
|  ├─ index.js
|  └─ package.json
└─ bar
   ├─ index.js
   └─ package.json

可以看到,hoist机制下,bar被提升到了顶层。如果同一个包的多个版本在项目中被依赖时,node_modules结构又是怎么样的?

例如:一个项目App直接依赖了A(version: 1.0)C(version: 1.0)AC都依赖了不同版本的B,其中A依赖B 1.0C依赖B 2.0,可以通过下图清晰的看到npm2npm3+结构差异:

image.png

B 1.0被提升到了顶层,这里需要注意的是,多个版本的包只能有一个被提升上来,其余版本的包会嵌套安装到各自的依赖当中(类似npm2的结构)。

image.png

至于哪个版本的包被提升,依赖于包的安装顺序!

依赖变更会影响提升的版本号,比如变更后,有可能是B 1.0 ,也有可能是 B 2.0被提升上来(但只能有一个版本提升)

细心的小伙伴可能发现,这其实并没有解决之前的问题,反而又引入了新的问题

image.png

npm3+和yarn存在的问题

Phantom dependencies 幽灵依赖

Phantom dependencies 被称之为幽灵依赖幻影依赖,解释起来很简单,即某个包没有在package.json 被依赖,但是用户却能够引用到这个包。

引发这个现象的原因一般是因为 node_modules 结构所导致的。例如使用 npm或yarn 对项目安装依赖,依赖里面有个依赖叫做 foofoo 这个依赖同时依赖了 bar,yarn 会对安装的 node_modules 做一个扁平化结构的处理,会把依赖在 node_modules 下打平,这样相当于 foobar 出现在同一层级下面。那么根据 nodejs 的寻径原理,用户能 require 到 foo,同样也能 require 到 bar

nodejs的寻址方式:(查看更多)

  1. 对于核心模块(core module) => 绝对路径 寻址

  2. node标准库 => 相对路径寻址

  3. 第三方库(通过npm安装)到node_modules下的库:        3.1.  先在当前路径下,寻找 node_modules/xxx
           3.2  递归从下往上到上级路径,寻找 ../node_modules/xxx
           3.3  循环第二步
           3.4  在全局环境路径下寻找 .node_modules/xxx

NPM doppelgangers NPM分身

这个问题其实也可以说是 hoist 导致的,这个问题可能会导致有大量的依赖的被重复安装.

举个例子:项目中有packageApackageBpackageCpackageD

### pnpm 全局安装失败的解决方案 当尝试全局安装 `pnpm` 时出现问题,可能是由多种原因引起的。以下是可能的原因分析以及对应的解决方法: #### 1. 权限不足 如果当前用户权限不足以执行全局安装操作,则可能会导致安装失败。可以通过以下方式解决问题: - 使用管理员权限运行终端或命令提示符。 - 或者,在命令前加上 `sudo`(适用于 macOS 和 Linux),例如: ```bash sudo npm install -g pnpm ``` 这一步骤有助于确保有足够的权限完成安装过程[^4]。 --- #### 2. NPM 版本过低 较旧版本的 NPM 可能存在兼容性问题,从而影响 `pnpm` 的安装。建议先将 NPM 更新至最新版本后再重试安装: ```bash npm install -g npm@latest ``` 完成后再次尝试安装 `pnpm`: ```bash npm install -g pnpm ``` 此步骤能够有效减少因 NPM 过时而导致的问题[^3]。 --- #### 3. 路径配置错误 有时即使成功安装了 `pnpm`,但由于路径未正确设置,仍然会显示找不到该命令的情况。此时需确认系统的 PATH 环境变量是否包含了 NPM 全局模块所在的目录。通常情况下,默认位置为 `/usr/local/bin` 或 `%AppData%\npm\bin`(Windows)。可通过以下命令验证: ```bash echo $PATH # 对于 Unix-like 系统 echo %PATH% # 对于 Windows 系统 ``` 如果没有包含上述路径,请手动将其添加到环境变量中并重启终端[^5]。 --- #### 4. 缓存清理 NPM 的缓存损坏也可能阻碍软件包的正常安装。可以清除现有缓存后重新尝试安装: ```bash npm cache clean --force npm install -g pnpm ``` 这一措施可以帮助排除潜在的缓存相关问题。 --- #### 5. 替代安装方法 如果以上方法均未能奏效,还可以考虑使用其他方式进行安装。例如利用官方推荐的方式直接从源码构建或者借助工具如 npx 完成临时调用: ```bash npx pnpm <command> ``` 另外也可以按照文档指引通过独立脚本来部署[^1]。 --- ### 验证安装结果 无论采用哪种修复手段,最后都应检验是否真正完成了安装工作。输入下面这条指令查看其返回值即可判断状况如何: ```bash pnpm -v ``` 若顺利显示出具体版本号则表明一切就绪。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值