从 npm 切换到 pnpm,真香!

大厂技术  高级前端  Node进阶

点击上方 程序员成长指北,关注公众号

回复1,加入高级Node交流群

转转的 CI 系统和开发环境为什么要从 npm 切换到 pnpm 呢。因为在使用 npm 的时候,遇到几个问题。

  1. 磁盘空间占用过大

  2. 首次安装速度慢

  3. 幽灵依赖导致一些报错

那 pnpm 又是怎么解决上面的问题呢?

什么是 pnpm

pnpm 是新一代包管理工具,为什么叫 pnpm 呢,是因为 pnpm 作者对现有的包管理工具,尤其是 npm 和 yarn 的性能特别失望,所以起名叫做 performance npm,即 pnpm(高性能 npm)

我们今天要使用 pnpm,那 pnpm 有哪些优势呢

1、npm 的问题

在 npm@3 之前,node_modules 结构是干净、可预测的,因为 node_modules 中的每个依赖项都有自己的 node_modules 文件夹,在 package.json 中指定了所有依赖项,比如项目 a 依赖项目 b,项目 c 也依赖项目 b,这样如果 a 和 c 依赖的 b 的版本不一致,也不会出问题

node_modules
└─ a
   ├─ index.js
   ├─ package.json
   └─ node_modules
      └─ b
         ├─ index.js
         └─ package.json
   c
   ├─ index.js
   ├─ package.json
   └─ node_modules
      └─ b
         ├─ index.js
         └─ package.json

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

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

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

为了解决上面的问题,npm 提出了 node_modules 扁平化结构,在 npm@3+ 和 yarn 中,node_modules 结构变成:

node_modules
├─ a
|  ├─ index.js
|  └─ package.json
└─ b
|  ├─ index.js
|  └─ package.json
└─ c
   ├─ index.js
   └─ package.json

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

c4afb2b36f0eff994f1f093f9b19cc66.jpeg

包 B 1.0 被提升到了顶层,这里需要注意的是,多个版本的包只能有一个被提升上来,其余版本的包会嵌套安装到各自的依赖当中,至于哪个版本的包被提升,依赖于包的安装顺序!

扁平化之后,又引入了新的问题幽灵依赖,解释起来很简单,即某个包没有在 package.json 被依赖,但是用户却能够引用到这个包。还有 NPM doppelgangers 问题,当包有多个版本,会被重复安装多次。

2、pnpm 的方案

pnpm 使用的是 npm version 2.x 类似的树形结构,同时使用.pnpm 以平铺的形式储存着所有的包。

我们称.pnmp 为虚拟存储目录,该目录通过 <package-name>@<version> 来实现相同模块不同版本之间隔离和复用,由于它只会根据项目中的依赖生成,并不存在提升,所以它不会存在之前提到的 Phantom dependencies 问题!

然后使用 Store + Links 和文件资源进行关联。简单说 pnpm 会把包下载到一个公共目录,如果某个依赖在 sotre 目录中存在了话,那么就会直接从 store 目录里面去 hard-link,避免了二次安装带来的时间消耗,如果依赖在 store 目录里面不存在的话,就会去下载一次。

通过 Store + hard link 的方式,不仅解决了项目中的 NPM doppelgangers 问题,项目之间也不存在该问题,从而完美解决了 npm3+和 yarn 中的包重复问题!

f1cfe67ed9b409b76bfa325e3388ea2c.jpeg
3、workspace

pnpm 除了安装速度快,节省磁盘空间,避免幽灵依赖等优化,也内置了对 monorepo 的支持。使用起来比较简单,在项目根目录中新建 pnpm-workspace.yaml 文件,并声明对应的工作区就好。

packages:
  # 所有在 packages/ 子目录下的 package
  - 'packages/**'

切换到 pnpm

转转的 CI 系统。一共有 6 台机器,是前后端公用的。之前使用 npm 存在几个问题。第一个就是安装速度慢,导致编译时间过长。第二个是 node_modules 过大。导致每天必须清除一下机器上 node_modules,不然就会出现磁盘空间不足的问题。切换成 pnpm 之后,我们测试的结果,单台机器最少能节省了 30G 的空间,安装速度提升一倍以上。

因为直接从 npm 切换到 pnpm,大多数的项目都会存在幽灵依赖的问题。导致项目报错。我们的切换方案是在项目设置中勾选是否使用 pnpm。默认是 npm。单个项目在本地切换之后,在 CI 平台上设置成 pnpm 就完成了升级。

切换 pnpm 的一些问题
  • 使用 pnpm install --shamefully-hoist

如果依赖一直有问题,可以使用 pnpm install --shamefully-hoist 创建一个扁平 node_modules 目录结构, 类似于 npm 或 yarn

  • 解决幽灵依赖时,安装默认的包导致报错

先使用 npm 安装,生成 package-lock.json, 安装缺少的包时,使用 lock 里面的版本

  • 即使删除了 node_modules 和 lock 文件,安装时,特定的包还是报错

比如我们在升级时,一个包把最新的版本删除了。导致安装时一直失败。可以尝试使用 pnpm store prune 来删除

Node 社群

我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。

a8c403d972b729725a9fe07ac6e0aa1f.jpeg

如果你觉得这篇内容对你有帮助,我想请你帮我2个小忙:

1. 点个「在看」,让更多人也能看到这篇文章

2. 订阅官方博客 www.inode.club 让我们一起成长

点赞和在看就是最大的支

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值