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

news/2024/12/22 8:53:17/

作者:京东零售 杨秀竹

pnpm 是什么

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

pnpm 优势

更快的依赖安装速度

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

actioncachelockfilenode_modulesnpmpnpmYarnYarn PnP
install37.6s17.3s22.1s20.2s
install2.1s1.4s695msn/a
install8.8s4.7s8.8s668ms
install13.1s8s22.8s15.2s
install13.7s14.7s8.9s670ms
install2.6s4s16sn/a
install2s1.4s681msn/a
install2.5s14.1s16.6sn/a
updaten/an/an/a8.3s7.4s8.7s16.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)

links

pnpm 通过链接( links)与全局存储空间(store)管理的不同项目的 node_modules 依赖。硬链接(hard links)能指向磁盘上原始文件所在的同一位置(store),但是因为 pnpm 的 node_modules 是树形目录结构,且硬链接只能用于文件不能用于目录,因此需要通过软链接(symbolic link)来实现目录寻址,通过如下一张项目依赖关系图可以更好的理解 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 不可以跨多个驱动器或文件系统工作,即不同的系统磁盘目录都会存处一份依赖包。

项目应用

从 npm、yarn 进行迁移的过程

pnpm 的安装

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

npm install -g pnpm
Node.jspnpm 5pnpm 6pnpm 7pnpm 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 分身的问题,提升了依赖包的安装速度,减小了磁盘空间占用。


http://www.ppmy.cn/news/70455.html

相关文章

SQL 常用函数总结(二)

字符串处理函数 1. CONCAT() 函数功能:将两个或多个字符串合并成一个字符串。 函数语法: CONCAT(string1, string2, ...)string1、string2 等的数量可以是零个或多个,分别表示需要合并的字符串。 使用示例: 假设现在有一个名…

软件测试工程师的职业发展方向

一、软件测试工程师大致有4个发展方向: 1 资深软件测试工程师 一般情况,软件测试工程师可分为测试工程师、高级测试工程师和资深测试工程师三个等级。 达到这个水平比较困难,这需要了解很多知识,例如C语言,JAVA语言&#xff0c…

多尺度样本熵

多尺度样本熵及其MATLAB实现方法 随着人们对信号处理技术的不断深入研究和发展,在信号非线性、非高斯的情况下,熵的概念成为一种很重要的测量信号复杂度的度量方式。多尺度熵是指在多个尺度范围内测量信号复杂度的一种方法。本文将介绍多尺度样本熵的概…

什么是前端宏任务,什么又是前端微任务呢?一文读懂前端微任务宏任务。

在前端中,宏任务和微任务是异步任务的两种不同类型。 前端有很多中异步任务类型。 可以分为三类: 宏任务 定时器任务用户交互事件任务(鼠标事件、键盘事件)网络请求任务I/O操作任务(读写文件) 微任务 Pro…

TPC 网络通信基础(二)

文件下载利用 tcp原理 Ubuntu 20.04 python3.7 三个python文件 客户端.py 服务器.py 文件.py 客户端充当用户 服务器充当提供下载的服务端 客户端代码: import socketdef main():# 创建套接字tcp_socket socket.socket(socket.AF_INET,socket.SOCKET_…

String StringBuilder常用方法总结

在java中String类不可变的,创建一个String对象后不能更改它的值。所以如果需要对原字符串进行一些改动操作,就需要用StringBuilder类或者StringBuffer类,StringBuilder比StringBuffer更快一些,缺点是StringBuilder不是线程安全的&…

JAVA面试-语法基础- A01

语法基础 面向对象封装继承多态 面向对象 面向对象特性 封装 利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分隔的独立实体,数据被保护在抽象数据类型的内部,尽可能的隐藏内部的细节,只保留一些对外的接口…

前端通信-服务端发送事件: SSE(Server-Sent Events)

在日常开发中,我们经常会遇到需要实时获取数据的情况,之前实现这种相似的功能通常都是用ajax长轮询,在HTML5规范中定义了新的通信方式,WebSocket和SSE。websocket相对SSE更常用一些,本文着重来介绍SSE的应用。 SSE AP…