【前端工程化】pnpm为什么这么火?一大原因离不开这一点

前言

在一个项目中最头疼的问题就是依赖装不上,项目一直启动不起来,有些不太耐心的新同学就很容易放弃。

幽灵依赖一直是前端工程化包管理器的一个重点问题,pnpm包管理器火起来的一大原因就是,他解决了幽灵依赖这个问题。

今天这篇文章就将带你彻底认识node_modules以及它产生的问题:幽灵依赖

发展历程

嵌套排序

相传在很久很久以前,node_modules还是非常质朴纯粹的,我们叫它小N,小N有两个包一个叫package-A一个叫package-B,这两个包呢有一个共同点,都有lodash这个包。

此时小N是这么处理的,目录结构如下:
在这里插入图片描述
这就是最初的node_modules处理的方式:嵌套结构。一个包嵌套着N个包。

相信大家都会发现一个问题,如果lodash包还引入着其他包是不是一直需要递归下去,还有就是lodash这个包下载太多次浪费空间。

总结一下这种方式:

  • 嵌套过深
  • 占用空间过大

平铺结构

小N为了解决这个问题,把lodash包提升同一级目录
在这里插入图片描述
小N处理同一版本的包就像上面那样,如果用的同一个包的不同版本,取高版本
在这里插入图片描述

幽灵依赖

当一个包被提升到一个上层目录,而主项目仍然在其依赖中引用该包时,会导致一种看似正常但潜在危险的情况。让我通过一个例子来说明这个问题:

假设有一个项目结构如下:

project/
  ├── node_modules/
  │     ├── package-A/
  │     │     ├── lodash@1.0.0/
  │     │     └── ...
  │     └── ...
  ├── package.json
  └── ...

在这个项目中,package-A 使用了 lodash@1.0.0 版本作为其依赖,并且已经被提升到了项目的顶层 node_modules 目录中。

主项目的 package.json 文件中可能会包含以下内容:

{
  "name": "main-project",
  "dependencies": {
    "package-A": "^1.0.0"
  }
}

这时,主项目依赖于 package-A,而 package-A 实际上已经被提升到了顶层的 node_modules目录。

一段时间后,开发者决定废弃使用 package-A,并将其从项目中移除。但是,他们忘记了移除主项目中对于 package-A 的依赖引用。

随后,由于某些原因,项目的顶层 node_modules 目录被清理,其中的所有依赖项都被删除,包括了 package-A

此时,当主项目尝试运行时,会发现虽然 package.json 中声明了对于 package-A 的依赖,但是在实际的 node_modules 目录中找不到这个包,因为它已经被废弃并且删除了。

这将导致主项目无法找到所需的包而报错,尽管一开始没有报错,因为当时 package-A 被提升到顶层 node_modules 目录中。

pnpm

它解决了 npm/yarn 平铺 node_modules 带来的依赖项重复的问题

假设存在依赖:

├── package-a
│   └── lodash@4.0.0
├── package-b
│   └── lodash@4.0.0
├── package-c
│   └── lodash@3.0.0
└── package-d
    └── lodash@3.0.0

那么不可避免地在 npm 或者 yarn 中,lodash@3.0.0 会被多次安装,无疑造成了空间的浪费与诸多问题。
在这里插入图片描述
而pnpm使用软硬链接去下载依赖,下载到全局中,并且同一个依赖只会在全局下载一次。

./node_modules/package-a       ->  .pnpm/package-a@1.0.0/node_modules/package-a
./node_modules/package-b       ->  .pnpm/package-b@1.0.0/node_modules/package-b
./node_modules/package-c       ->  .pnpm/package-c@1.0.0/node_modules/package-c
./node_modules/package-d       ->  .pnpm/package-d@1.0.0/node_modules/package-d
./node_modules/.pnpm/lodash@3.0.0
./node_modules/.pnpm/lodash@4.0.0
./node_modules/.pnpm/package-a@1.0.0
./node_modules/.pnpm/package-a@1.0.0/node_modules/package-a
./node_modules/.pnpm/package-a@1.0.0/node_modules/lodash     -> .pnpm/package-a@1.0.0/node_modules/lodash@4.0.0
./node_modules/.pnpm/package-b@1.0.0
./node_modules/.pnpm/package-b@1.0.0/node_modules/package-b
./node_modules/.pnpm/package-b@1.0.0/node_modules/lodash     -> .pnpm/package-b@1.0.0/node_modules/lodash@4.0.0
./node_modules/.pnpm/package-c@1.0.0
./node_modules/.pnpm/package-c@1.0.0/node_modules/package-c
./node_modules/.pnpm/package-c@1.0.0/node_modules/lodash     -> .pnpm/package-c@1.0.0/node_modules/lodash@3.0.0
./node_modules/.pnpm/package-d@1.0.0
./node_modules/.pnpm/package-d@1.0.0/node_modules/package-d
./node_modules/.pnpm/package-d@1.0.0/node_modules/lodash     -> .pnpm/package-d@1.0.0/node_modules/lodash@3.0.0

lodash@3.0.0lodash@4.0.0 会生成一个指向全局目录的硬链接,如果新项目依赖二者,则可复用存储空间。

小结

总结来说,通过上述的特殊方式,pnpm 能够高效地解决幽灵依赖问题,实现更节省空间、更稳定的包管理。这也是为什么 pnpm 在前端社区引起关注的一个原因。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冰镇白干

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

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

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

打赏作者

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

抵扣说明:

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

余额充值