原文:https://lwebapp.com/zh/post/pnpm-patch-package

介绍

前端开发过程中,经常会遇到第三方开源库有 BUG 的情况,通常我们有以下处理方式

  1. 自己 fork 一份源码修改,修复完后就可以本地打包直接用了。如果你想分享你的研究成果给其他人,可以再传到 npm 仓库或者提交 PR 给源仓库。这种方式有个缺点,就是笔记难保持和官方库的同步。
  2. 等待库作者修复。这种方式不太靠谱,因为开源作者一般都会比较忙,你的需求可能不会排在前面。

有些小伙伴不知道,还有一种方案是给本地 npm 包打补丁。意思是你的项目在正常安装某个 npm 依赖的情况下,通过在项目里增加一个补丁文件,就可以将对这个 npm 包的修改持久保存到项目中。这样就能实现针对开源库的 bug 修复直接应用到项目中。

小编了解到有一个叫 patch-package 的开源库,可以轻松的做到给 node_modules 的库打补丁。接下来我们看看如何使用 patch-package ,以及使用过程中有什么问题。

如何使用 patch-package

参照官方的教程,简单几步即可快速给本地 npm 包打补丁。

  1. 从 node_modules 中找到 npm 依赖包的源码,修复依赖包中的错误
vim node_modules/my-package/common.js
  1. 运行 patch-package 创建一个 .patch 文件,.patch 文件可以自动被 npm 识别并应用
npx patch-package my-package
  1. 提交补丁文件就可以与您的团队共享修复了
git add patches/my-package+3.14.15.patch
git commit -m "fix common.js in my-package"
  1. 安装下依赖包
npm i -D patch-package
  1. 在 package.json 中添加一个脚本 postinstall,支持在 npm i 之后就会自动执行 patch-package 将补丁应用上
 "scripts": {
"postinstall": "patch-package"
}

由于小编用的 pnpm 包管理器,在执行 npx patch-package my-package时候报错了

**ERROR** No package-lock.json, npm-shrinkwrap.json, or yarn.lock file.

You must use either npm@>=5, yarn, or npm-shrinkwrap to manage this project's
dependencies.

大概意思是支持npm、yarn包管理器,不支持pnpm。

官方也确实有 bug ,截止发稿日 2022 年 6 月 18 日,这个问题还是没有被修复的。

有人已经给 patch-package 提过 bug 了,见issue :How to execute patch to dependencies in other dependencies, when using pnpm #338

不过小编能力有限,只能另辟蹊径,采取变通方案

pnpm 打补丁

pnpm包管理器下给npm依赖包打补丁的思路是,将要修复的源码文件复制出来,放到项目里,在每次执行 npm i 安装依赖之后,用nodejs脚本将修改后的文件复制到源码目录中覆盖掉源代码,实现修改代码的目的。

  1. 修改好node_modules中依赖包源码文件,复制到跟目录的patches目录下
vim node_modules/my-package/common.js
cp node_modules/my-package/common.js patches/my-package
  1. 在项目中新建一个脚本postinstall.js,实现覆盖源代码文件的操作
copyFileSync('./patches/my-package/common.js', './node_modules/my-package/common.js');

function copyFileSync(source, target) {
var targetFile = target; // If target is a directory, a new file with the same name will be created
if (fs.existsSync(target)) {
if (fs.lstatSync(target).isDirectory()) {
targetFile = path.join(target, path.basename(source));
}
} fs.writeFileSync(targetFile, fs.readFileSync(source));
}
  1. package.json 中新增一个postinstall命令指向我们的脚本
 "scripts": {
"postinstall": "node scripts/postinstall.js"
}

总结

以上就是小编在一个使用pnpm包管理器的项目中实现给npm包打补丁的方案,如果您有更好的解决思路,欢迎分享出来。

参考

pnpm 中无法使用 patch-package 打补丁的更多相关文章

  1. 为什么多线程、junit 中无法使用spring 依赖注入?

    为什么多线程.junit 中无法使用spring 依赖注入? 这个问题,其实体现了,我们对spring已依赖太深,以至于不想自己写实例了. 那么到底是为什么在多线程和junit单元测试中不能使用依赖注 ...

  2. Linux-学习patch命令打补丁,diff命令制作补丁(3)

    patch:通过补丁文件,来对原文件打补丁 diff:      比较两个文件,然后生成一个补丁文件 1.patch用法    patch -p[剥离层级]  <[补丁文件] 2.patch命令 ...

  3. java中不带package和带package的编译运行方式

    Java中不带package的程序和带package的程序编译的方式是不同的. 一.不带package的程序建立个HelloWorld.java的文件,放入C:\,内容如下:public class ...

  4. block中无法使用C数组变量

    在Objective-C的block中无法使用C数组,即使我们不对C数组做任何改变,编译的时候也会报错: #include <stdio.h> int main() { const cha ...

  5. 自坑实录 - Asp.net MVC中无法使用@Ajax.BeginForm问题解决

    创建空的web项目,通过Nuget引用mvc组件来搭建空的MVC项目时, 在视图页面中无法使用@Ajax.BegForm来进行异步提交数据, 而新建默认的MVC模板项目却能够正常使用@Ajax.Beg ...

  6. model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转;解决的方法是用responsewrite(普通的字符响应)

    model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转:解决的方法是用responsewrite

  7. Ruby中使用patch HTTP方法

    Ruby中使用patch HTTP方法 如果使用patch,在后台可以看到只更新了改动的部分: Started PATCH "/ads/5/update" for ::1 at 2 ...

  8. CenterOS7中解决No package mysql-server available.

    CenterOS7中解决No package mysql-server available. 1.使用yum install -y mysql-server报错如下: [root@heyong_jd ...

  9. 巧用svn create patch(打补丁)方案解决定制版需求

    最近项目定制版越来越多,维护,同步代码非常费事.以前的思路如下图: 以前的svn目录结构如下图: 这样问题有2个: 若在一个定制包中修复了其他定制包也有的bug,同步更新其他包的代码时,非常费劲+机械 ...

  10. Java中import及package的用法

    有些人写了一阵子 Java,可是对於 Java 的 package 跟 import 还是不 太了解很多人以為原始码 .java 档案中的 import 会让编译器把所 import 的程式通通写到编 ...

随机推荐

  1. [OpenCV实战]40 计算机视觉工具对比

    文章目录 1 简介 2 适用于计算机视觉的MATLAB 2.1 为什么要使用MATLAB进行计算机视觉:优点 2.2 为什么不应该将MATLAB用于计算机视觉:缺点 3 适用于计算机视觉的OpenCV ...

  2. C++ 使用 new 创建二维数组

    1. 直接创建 C++ 使用 new 创建二维数组最直接的方法就是 new T[M][N].返回的指针类型是 T (*)[N],它是指向数组的指针,可以直接使用数组下标形式访问元素.释放内存直接使用d ...

  3. vulnhub靶场之HACKATHONCTF: 2

    准备: 攻击机:虚拟机kali.本机win10. 靶机:HackathonCTF: 2,下载地址:https://download.vulnhub.com/hackathonctf/Hackathon ...

  4. Linux的串口非标准波特率设置更改

    用的是全志的R528 SDK,Linux内核是5.4,新增加一个250000的非标准波特率 参考网络大神文档,实践并记录宝贵的经验. 方法: 1.修改内核的/include/uapi/asm-gene ...

  5. 關於scanf()的使用

    要使用scanf函數進行輸入: 1.如果用scanf()要輸入讀取基本變量的值,需要加&. 2.如果用scanf()讀取的是把字符串讀入字符數組中,則不需要加& 1 #include& ...

  6. 2023牛客寒假算法基础集训营3 A-I+K

    A 题解 知识点:贪心. 把所有正偶数除成奇数,即可. (人傻了没加 \(x>0\) WA2 时间复杂度 \(O(n)\) 空间复杂度 \(O(1)\) 代码 #include <bits ...

  7. mysql常用命令,检查数据库连接情况以及修改时区

    常用操作 注:也可以运行 mysql -u 用户名(root) -p 密码(root) 数据库名(bank) ,然后回车 导入文件:source e:bank.sql (你的sql文件) 回车 PS ...

  8. 踩坑实录---Angular防抖——点击事件

    npx ng g directive DebounceClickDirective --module=app 然后自动生成了2 个文件 CREATE src/app/debounce-click-di ...

  9. react 高效高质量搭建后台系统 系列 —— 系统布局

    其他章节请看: react 高效高质量搭建后台系统 系列 系统布局 前面我们用脚手架搭建了项目,并实现了登录模块,登录模块所依赖的请求数据和antd(ui框架和样式)也已完成. 本篇将完成系统布局.比 ...

  10. 【SW】利用3D打印机打印 PCB 钢网的方法

    每完成一个小作品以后,PCB打样回来,手工焊接着费时费力,定制钢网又未免太过浪费,想到自己有一台 FDM 3D 打印机,是不是可以通过 3D 打印机打印 "钢网" 呢? 在网上也翻 ...