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

news/2024/9/15 21:21:06/

作者:京东零售 杨秀竹

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…

滨州申请专利需要准备哪些材料?

如果你想保护你的一些发明和设计,你可以申请专利。申请专利时,需要提前了解程序和相关流程。那么,申请专利需要准备哪些材料呢?让我们一起仔细看看。 首先,申请专利需要准备哪些材料? (1)外观专利&#xff…

C++学习 Day14

目录 1. 泛型编程 2. 函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 3. 类模板 3.1 类模板的定义格式 3.2 类模板的实例化 1. 泛型编程 如何实现一个通用的交换函数呢? void Swap(int&a…

德尔玛IPO首日破发,市值蒸发超4亿

今日(5月18日),小米“代工厂”广东德尔玛科技股份有限公司(下称“德尔玛”,301332.SZ)正式在深交所挂牌上市。 德尔玛此次IPO募资净额为12.31亿元,开盘价为14.81元/股,与发行价持平…

【Linux内核解析-linux-5.14.10】文件系统知识点以及解答(建议收藏)

什么是Linux文件系统? 答:Linux文件系统是一种用于管理和组织计算机上数据的方法。它提供了一个层次结构,使用户能够轻松地访问他们的数据,并且支持对数据进行备份、恢复和保护。 Linux中有哪些常见的文件系统类型? 答…

使用 SpringBoot 访问 MySQL 数据库

一、目标 创建一个 MySQL 数据库,构建一个 Spring 应用程序,并将其连接到新创建的数据库。 二、准备工作 1、最喜欢的文本编辑器或 IDE 2、Java 17或更高版本 3、Gradle 7.5或Maven 3.5 三、初始化项目 1、 导航到https://start.spring.io。该服务…

HTTPTomcatServlet学习

HTTP&Tomcat 今日目标: 了解JavaWeb开发的技术栈理解HTTP协议和HTTP请求与响应数据的格式掌握Tomcat的使用掌握在IDEA中使用Tomcat插件理解Servlet的执行流程和生命周期掌握Servlet的使用和相关配置 1. Web概述 1.1 Web和JavaWeb的概念 Web是全球广域网&…

freeswitch的2833和inband对接方案

概述 freeswitch支持三种模式的DTMF传输方式,分别时inband、INFO、2833。 在传统的PSTN网络中,所有的DTMF码都是inband模式,所以VOIP网络和PSTN网络对接中,需要将DTMF码做格式转换,通常是2833和inband之间的转换。 …

Makefile 简易教程

如果你是命令行重度使用者,学习 Makefile 将可以大大提高你的开发效率,下面简单介绍一下 Makefile 的知识和使用方式。 Makefile 是一种包含一组指令来编译和构建软件项目的文件。 Makefile 文件通常包含一组规则和依赖关系,以指定如何将源…

Netty核心组件模块(一)

1.Bootstrap和ServerBootstrap 1>.Bootstrap意思是引导,一个Netty应用通常由一个Bootstrap开始,主要作用是配置整个Netty程序,串联各个组件,Netty中Bootstrap类是客户端程序的启动引导类,ServerBootstrap是服务端启动引导类; 2>.常见的方法有: ①.public ServerBootstr…

【笔试强训选择题】Day13.习题(错题)解析

作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:笔试强训选择题 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!! 文章目录…

spring项目里的大事务优化

编程型事务更加灵活 声明式事务只需要加在方法头加Transactional注解即可开启事务,但是还是不太灵活,意味着整个方法所进行对数据库操作都要加进事务,当然一次查询也要进入事务,这并不是我们想要的,我们在update、ins…

SpringMVC 执行流程

视图阶段(老旧JSP等) DispatcherServlet:接收请求、响应结果,所有的请求都要经过它,它是被Tomcat容器初始化的当这个类加载时会加载一些组件类HandlerMapping、HandlerAdapter、ViewResolver等等。 HandlerMapping:根…