包管理工具:pnpm | 京东云技术团队

京东云开发者
• 阅读 421

作者:京东零售 杨秀竹

pnpm 是什么

pnpm( performant npm )指的是高性能的 npm,与 npm 和 yarn 一样是一款包管理工具,其根据自身独特的包管理方法解决了 npm、yarn 内部潜在的安全及性能问题,在多数情况下拥有更快速的安装速度、占用更小的存储空间,结合官网给出的性能测试及项目中的使用表现,其具有良好的应用前景。

pnpm 优势

更快的依赖安装速度

pnpm 通过特有的依赖管理方式,使其与其他包管理器相比具有更快的依赖安装速度,下图是官网给出的性能测试数据,在不同情况下安装、更新依赖包的速度性能表现,可以看出在多数情况下其耗时相比于其他包管理工具更短。

action cache lockfile node_modules npm pnpm Yarn Yarn PnP
install 37.6s 17.3s 22.1s 20.2s
install 2.1s 1.4s 695ms n/a
install 8.8s 4.7s 8.8s 668ms
install 13.1s 8s 22.8s 15.2s
install 13.7s 14.7s 8.9s 670ms
install 2.6s 4s 16s n/a
install 2s 1.4s 681ms n/a
install 2.5s 14.1s 16.6s n/a
update n/a n/a n/a 8.3s 7.4s 8.7s 16.9s

更小的包管理空间

使用 pnpm 时,依赖会被存储在内容可寻址的同一存储空间,可以节省大量的磁盘空间。

1、如果你用到了某依赖项的不同版本,只会将不同版本间有差异的文件添加到仓库(store)。

例如,如果某个包有100个文件,而它的新版本只改变了其中1个文件。那么 pnpm update 时只会向存储中心额外添加1个新文件,而不会因为仅仅一个文件的改变复制整新版本包的内容。

2、所有文件都会存储在硬盘上的某一位置。

当软件包被被安装时,包里的文件会硬链接到这一位置,而不会占用额外的磁盘空间这允许你跨项目地共享同一版本的依赖。

更高效安全的依赖管理方式

npm3 与 yarn 存在幽灵依赖(Phantom dependencies)以及 NPM分身(NPM doppelgangers )问题

pnpm 默认创建一个非平铺的 node_modules 及网状链接的包管理方式,因此代码无法访问任意包避免了幽灵依赖问题;又因为依赖始终都是存在 store 目录下,通过硬链接(hard links)进行寻址,一份相同的依赖始终只会被安装一次,因此可以避免 npm 分身问题。

幽灵依赖:某个包没有在 package.json 被依赖,但是用户却能够引用到这个包
npm包分身:在 npm3+ 和 yarn 中,由于存在 hoist 机制,可能大量的依赖被重复安装,导致 npm/yarn 的性能损失

独特的依赖管理方式( links + store)

pnpm 通过链接( links)与全局存储空间(store)管理的不同项目的 node_modules 依赖。硬链接(hard links)能指向磁盘上原始文件所在的同一位置(store),但是因为 pnpm 的 node_modules 是树形目录结构,且硬链接只能用于文件不能用于目录,因此需要通过软链接(symbolic link)来实现目录寻址,通过如下一张项目依赖关系图可以更好的理解 pnpm 是如何进行依赖寻址的。

包管理工具:pnpm | 京东云技术团队

store

例如,如果您的项目中多处都使用 foo 包并且它占用 1MB 的空间,那么看起来它在项目的 node_modules 文件夹中占用了与全局存储(.pnpm store)相同的 1MB 空间。 但是,该 1MB 是磁盘上两个不同位置的相同空间 , 所以 foo 总共占用 1MB,而不是 2MB。

pnpm 会使用名为 .pnpm-store 的存储路径来存储该磁盘项目下的所有 node_modules 依赖,通常是在项目的根目录下,Mac/linux 中默认会设置到 {home dir}>/.pnpm-store/v3;windows 下会设置到当前盘的根目录下,比如D盘(D/.pnpm-store/v3)。由于硬链接寻址的限制,pnpm 不可以跨多个驱动器或文件系统工作,即不同的系统磁盘目录都会存处一份依赖包。

包管理工具:pnpm | 京东云技术团队

项目应用

从 npm、yarn 进行迁移的过程

pnpm 的安装

有无安装 nodejs,pnpm 都提供了对应的安装方式,具体指令可参考官网,将npm对应的指令置换为 pnpm 即可。在安装 pnpm 时需要注意 nodejs 的兼容版本

npm install -g pnpm
Node.js pnpm 5 pnpm 6 pnpm 7 pnpm 8
Node.js 12 ✔️ ✔️
Node.js 14 ✔️ ✔️ ✔️
Node.js 16 未知 ✔️ ✔️ ✔️
Node.js 18 未知 ✔️ ✔️ ✔️

lock文件迁移

通过 pnpm import 可以将npm、yarn的 lock 文件迁移生成 pnpm-lock.yaml 锁定依赖版本

总结

pnpm 通过软、硬链接(hark link、symbolic link) + 全局存储(store)结合的依赖管理方式完全实现了依赖树结构的包管理方式,解决了 npm3 及 yarn 中的幽灵依赖和 npm 分身的问题,提升了依赖包的安装速度,减小了磁盘空间占用。

点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
vue 环境搭建笔记
环境开发工具:VSCodevue版本:2.x准备使用npm包管理器进行安装,也可以使用yarn包管理器。可以使用淘宝的npm镜像,国内速度更快。使用方式:$npminstallgcnpmregistryhttps://registry.npm.taobao.org
Stella981 Stella981
3年前
Scapy 从入门到放弃
0x00前言最近闲的没事,抽空了解下地表最强的嗅探和收发包的工具:scapy。scapy是一个python模块,使用简单,并且能灵活地构造各种数据包,是进行网络安全审计的好帮手。0x01安装因为2020年python官方便不再支持python2,所以使用python3安装。!(https://oscimg.oschina.net/os
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Node.js学习笔记(二、NPM 使用)
介绍NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:允许用户从NPM服务器下载别人编写的第三方包到本地使用。允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
Stella981 Stella981
3年前
Bypass ngx_lua_waf SQL注入防御(多姿势)
0x00前言ngx\_lua\_waf是一款基于ngx\_lua的web应用防火墙,使用简单,高性能、轻量级。默认防御规则在wafconf目录中,摘录几条核心的SQL注入防御规则:select.(from|limit)(?:(union(.?)select))(?:from\Winformation_schema\W)这边
Stella981 Stella981
3年前
Linux应急响应(二):捕捉短连接
0x00前言​短连接(shortconnnection)是相对于长连接而言的概念,指的是在数据传送过程中,只在需要发送数据时,才去建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。在系统维护中,一般很难去察觉,需要借助网络安全设备或者抓包分析,才能够去发现。0x01应急场景​
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
如何编写一个健壮的 npm 包 | 京东云技术团队
比如老王我,用​​npminit​​新建一个包,改把改把,然后来个​​npmpublish​​,soeasy!Tooyoungtoonaive,baby!请容我讲述一些发布过程中踩过的坑。