【patch-package】修改node_modules下的依赖包源码

news2024/12/26 0:35:56

场景:当项目里使用的element-ui有bug,但是项目里又急需修改这bug,这个时候就需要给依赖打补丁啦~

1、patch-package

1.1、概念

lets app authors instantly make and keep fixes to npm dependencies. It's a vital band-aid for those of us living on the bleeding edge.

这是npm官网上对patch-package的说明,其意思就是可以让大家立即对npm依赖的源码进行自定义修改。其实大多数时候是不需要自己去改依赖源码的,毕竟大多数情况你写的代码肯定没别人作者自己写得好,但是遇到bug了,自己去及时改还是可以的

讲下几个简单参数(非全部参数)

--create-issue

 可能少数人会用,就是你找到这个bug,然后提出一个issue问题

--use-yarn

 如果你的项目里既有yarn又有npm,那么默认使用的是npm,加上这个参数的话,就可以指定用yarn

1.2、使用工具

常见的几个工具是 npm, yarn, pnpm

NPM:

npm i patch-package

YARN:

// v1.x:
yarn add patch-package postinstall-postinstall
// v2.x
yarn patch

PNPM:下面第二大点将会介绍使用方式

// v7.4.0 已经支持下面两指令
pnpm patch
pnpm pathc-commit

1.3、使用步骤

1、在npm或者yarn中安装patch-package依赖,安装方式在上面1.2里面

2、在package.json里按照下图方式来写

 3、在node_modules下对应依赖的源码中修改

下图我是在vue内核文件的computed源码里新增了一行打印

 4、新增补丁包

在终端输入 npx patch-package package-name,就可以看到在项目里新增了一个patches文件夹,那里面就是新增的补丁文件,这个package-name 就是你对应依赖的名字,切记这个名字是你依赖里的package.json的name,比如下图依赖名就是@vue/reactivity,此时你就输入下面指令(使用npx的话注意npm版本要大于5.2噢

npx patch-package @vue/reactivity

或者

yarn patch-package @vue/reactivity

那么第二个箭头是啥意思呢?其实这里很重要,因为你在依赖dist文件里会发现很多以cjs.js或者esm-bundler.js结尾的文件,所以一定要注意你改的是哪个文件,不然你改了后发现咋没效果呢,那就是路径错了,这个module就是类似于那个路径

5、重启项目

 当补丁包修改后,那就一定要重启项目了,不然不会生效,在vite框架里的话,就用下面方式来启动,因为vite框架热更新是利用node_modules下的.vite文件来的(预构建的概念),类似于缓存,所以 --force,就是不用缓存,重新构建的意思

yarn:
yarn dev --force
npm:
npm run dev --force

 2、pnpm patch

 上面说了 patch-package 适用于 npm和yarn上的,pnpm有自己的打补丁方式

2.1、先对依赖源码进行一次复制

pnpm patch reactivity@3.2.20

2.2、提示一个临时文件链接,在这链接里修改代码

C:\Users\xxx\AppData\Local\Temp

2.3、修改好后,执行下面指令新增补丁

pnpm patch-commit C:\Users\xxx\AppData\Local\Temp

2.4、修改package.json

当执行完上面指令后,项目会多一个文件夹:patches, 里面新增一个补丁文件:reactivity@3.2.20.patch,这个时候按照下面来修改package.json内容,不过最后都要重启项目噢

"pnpm": {
  "patchedDependencies": {
    "reactivity@3.2.20": "patches/reactivity@3.2.20.patch"
  }
}

3、问题答疑

1、补丁文件失效?

首先不管是npm,yarn或者pnpm下,都需要对要打补丁的依赖版本固定,如果后续团队中的其他成员依赖版本不一致,那么补丁不会生效的噢~

2、vite框架下都按照上述步骤来做了,但是为啥重启后没有生效?

首先vite为啥那么快的原因之一是 node_modules下的.vite文件会把加载的依赖做一个缓存的(vite预构建),你修改补丁后,照常 yarn dev 或者 npm run dev 重启的话,这个.vite 缓存还是存在的,所以你会发现页面并没有什么变化,这个时候,你可以 yarn dev --force重启,意思就是不使用缓存,重新构建依赖,或者删除.vite文件,再重新启动。但是实际上 ,一个yarn dev --force足够了

3、修改一些依赖,然后步骤都对了,也加了 --force,为啥重启不生效?(非常重要)

这种典型的依赖有一个: lodash,因为它依赖里没有package.json文件,就只有一个lodash.js,外面引用的时候,直接用的 import { slice } from 'lodash', 实际上引用的是 'node_modules/lodash/lodash.js', 其意思就是你是修改不了源码的(切记:我们想要修改依赖源码的前提,一定是依赖里要有自己的package.json),所以这种情况是没法打补丁的,那么针对有自己package.json的依赖修改文件后,一定要注意 package.json 里的module是不是你修改的那个文件,例如 你想修改 vue的内核源码,这个文件路径是 'node_modules/@vue/reactivity/dist/reactivity.cjs.js',你改了之后,按照步骤打包,然后--force重启,发现并没有生效,这个时候来看下 package.json的module里居然是 dist/reactivity.esm-bundler.js,这个时候问题就找到了,别人默认引用的是 esm-bundler.js后缀文件,而你修改的是cjs.js后缀文件,那肯定不生效啊!

4、打了补丁后,我不想要这个补丁了,怎么办?

这个时候如果你删除patches文件夹,再重启的话,其实是没有效果的,patches文件只会记录你修改了依赖的哪些东西,原因是 npx patch-package 已经将依赖代码修改了,所以你想要恢复的话,只有将之前的依赖源码还原回去,然后再 npx patch-package package-name(package-name为依赖名,可为路径名),这个时候重启,就会发现之前的源码又回来了

---有问题或者错误随便指出噢~---

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/161002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【hcip】mpls实验

目录 1.拓扑图 2.要求 3.主要配置 4.测试 1.拓扑图 2.要求 实现全网可达 3.主要配置 isp区域已配置ospf,bgp 然后配置mpls(r2) r2]mpls lsr-id 2.2.2.2 [r2]mpls Info: Mpls starting, please wait... OK! [r2-mpls]mpls ld [r2-mpls…

VTK-vtkPolyData解读

小结:本博文主要讲解vtkPolyData接口及常用的方法实现原理。 vtkPolyData 1描述 vtkPolyData是一系列的数据集包括vertices,lines,polygons,triangle strips。 vtkPolyData是vtkDataSet的具体实现,代表了一系列的几…

ELF文件格式解析

ELF文件是什么? ELF是Executable and Linkable Format的缩写,字面上看就是可执行和可连接文件。在Linux下可重定位文件(.o)、可执行文件、共享目标文件(.so)、核心转储问文件(core dump) 都是使用ELF文件格式。 ELF 通常由编译器或者连接器产生&#x…

2021年大数据挑战赛B题口罩佩戴检测求解全过程论文及程序

2021年大数据挑战赛 B题 口罩佩戴检测 原题再现: 新冠疫情的爆发对人类生命安全及全球经济发展造成了重大影响。虽然现在国内疫情基本得到有效遏制,但日常防控仍不可松懈。戴口罩是预防新冠肺炎最便捷、最有效的措施和方法。人脸佩戴口罩的自动化识别可…

2022跨境支付回顾,iPayLinks让“链接”更高效

从2015年服务第一个客户开始iPayLinks已陪伴用户走过8个春秋作为贴心的跨境资金管家iPayLinks跨越山海,链接全球以产品为基石这一年,iPayLinks持续开发新产品、新功能,帮助外贸企业和跨境卖家抓住机遇,降本增效。B2B外贸收款主打“…

Python 使用TF-IDF

第一个 简易版本 直接来至 jieba 包, 一下代码直接来源 https://blog.csdn.net/qq_38923076/article/details/81630442 这里记录 进行对比 jieba.analyse.extract_tags(sentence, topK20, withWeightFalse, allowPOS()) sentence:待提取的文本语料 topK…

【阶段三】Python机器学习25篇:机器学习项目实战:LigthGBM算法的核心思想、原理与LightGBM分类模型

本篇的思维导图: LigthGBM算法的核心思想 LigthGBM算法是Boosting算法的新成员,由微软公司开发。它和XGBoost算法一样是对GBDT算法的高效实现,在原理上与GBDT算法和XGBoost算法类似,都采用损失函数的负梯度作为当前决策树的残差近似值,去拟合新的决策树。 …

MATLAB实验五

实验五 A 1、在同一图形窗口绘制。利用plot绘图指令绘图命令。 (1)在窗口上部绘制正弦信号 x(t)sin(0.5πtπ4),t∈[0,4π]x(t)sin(0.5\pi t\frac \pi 4),t∈[0,4\pi]x(t)sin(0.5πt4π​),t∈[0,4π]。要求曲线为黑色实线。 (2&#xff…

QT(7)-初识委托

初识委托1 简介2 QT中的委托类2.1 函数2.1.1 关键函数2.1.2 其他函数3 例子3.1 官方例子3.2 修改官方例子4 设想1 简介 委托是Qt中的一种机制,用于在Qt模型/视图架构中处理特定类型的数据。委托提供了一种方便的方法来定制特定类型的数据的显示和编辑。 委托可以做…

天空卫士参与编写的《数据安全治理实践指南(2.0)》正式发布

2023年1月5日,由中国信息通信研究院(以下简称“中国信通院”)、中国通信标准化协会指导,中国通信标准化协会大数据技术标准推进委员会主办,数据安全推进计划承办的第二届数据安全治理峰会在北京召开。本次峰会发布多项…

算法刷题打卡第64天:平衡二叉树

平衡二叉树 难度:简单 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示例 1: 输入:root [3,9,…

错误票据(第四届蓝桥杯省赛C++A/B组,第四届蓝桥杯省赛JAVAA/B组)

题目详细:解题思路:这题的难点主要在于对于数据的读入以及对于两个数字的查找对于数据的读入:1.直接对单行字符串进行转换:题目所给出的输入只有行数并不知道一行有多少个数字所以我们采用一下读取一行然后对一行的结果进行读入首…

docker提交腾讯云标准模式

简介我们公司的容器化标准模式,本次是以redis为例进行示范技术要求:你会简单的docker容器打包环境需要:docker、docker-compose、联网环境、腾讯云容器及镜像服务(公司已有TKE)文件需要:除了你自己的Dockerfile所需要的东西外&…

TensorFlow 基础(三)梯度和自动微分

文章目录Computing gradientsGradient tapesGradients with respect to a modelControlling what the tape watchesIntermediate resultsGradients of non-scalar targetsCases where gradients returns NoneReferencesimport numpy as np import matplotlib.pyplot as pltimpo…

【自学Python】Python三目运算符

Python三目运算符 Python三目运算符教程 Python 中没有其他语言类型的三目运算符,但是我们可以借助 if 语句实现类似的三目运算符。 Python三目运算符详解 说明 Python 的三目运算符是借助于 if 语句来实现的。 语法 True_statements if condition else Fals…

千锋教育嵌入式物联网教程之系统编程篇学习-02

目录 系统调用函数与库函数 库函数的组成 库函数与系统调用的关系 进程概述 进程的定义 进程与程序的区别 进程的状态及其转换 进程的调度机制 进程控制块 查看当前系统所有进程 进程号函数 进程创建fork函数 进程挂起 进程的等待 wait() waitpid 特殊进程 …

CPU 运行时的硬件环境详解

注:本文参考小林coding相关文章,侵权请联系 目录 1.图灵机的工作方式 2.冯诺依曼模型 3.内存 4.中央处理器 5总线 6.输入、输出设备 7.线路位宽与 CPU 位宽 代码写了那么多,你知道 a 1 2 这条代码是怎么被 CPU 执行的吗? …

TCP/IP协议族之TCP、UDP协议详解(小白也能看懂)

前言 在进行网络编程之前,我们必须要对网络通信的基础知识有个大概的框架,TCP/IP协议族涉及到多种网络协议,一般说TCP/IP协议,它不是指某一个具体的网络协议,而是一个协议族。本篇章主要针对IP协议、TCP和UDP协议记录总…

常用的代码命名方法

常见的三种命名方法1 驼峰命名法(CamelCase)驼峰命名法应该我们最常见的一个,这种命名方式使用大小写混合的格式来区别各个单词,并且单词之间不使用空格隔开或者连接字符连接的命名方式1 大驼峰命名法(UpperCamelCase&…

Mysql 基础-持续更新

去重 DISTINCT DISTINCT 关键字的主要作用就是对数据表中一个或多个字段重复的数据进行过滤,只返回其中的一条数据给用户 注意点: DISTINCT 关键字只能在 SELECT 语句中使用。在对一个或多个字段去重时,DISTINCT 关键字必须在所有字段的最前…