原文: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. [python] 基于matplotlib_venn实现维恩图的绘制

    文章目录 VENN DIAGRAM(维恩图) 1. 具有2个分组的基本的维恩图 Venn diagram with 2 groups 2. 具有3个组的基本维恩图 Venn diagram with ...

  2. 火山引擎DataLeap数据调度实例的 DAG 优化方案

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群 实例 DAG 介绍 DataLeap 是火山引擎自研的一站式大数据中台解决方案,集数据集成.开发.运维.治理.资产管理能力 ...

  3. 【SpringBoot实战专题】「开发实战系列」从零开始教你舒服的使用RedisTemplate操作Redis数据

    SpringBoot快速操作Redis数据 在SpringBoot框架中提供了spring-boot-starter-data-redis的依赖组件进行操作Redis服务,当引入了该组件之后,只需要配 ...

  4. 【大型软件开发】浅谈大型Qt软件开发(一)开发前的准备——在着手开发之前,我们要做些什么?

    前言 最近我们项目部的核心产品正在进行重构,然后又是年底了,除了开发工作之外项目并不紧急,加上加班时间混不够了....所以就忙里偷闲把整个项目的开发思路聊一下,以供参考. 鉴于接下来的一年我要操刀这个 ...

  5. WeetCode4 —— 二叉树遍历与树型DP

    一丶二叉树的遍历 1.二叉树遍历递归写法与递归序 了解过二叉树的朋友,最开始肯定是从二叉树的遍历开始的,二叉树遍历的递归写法想必大家都有所了解. public static void process( ...

  6. SpringMVC学习笔记 - 第二章 - SSM整合案例 - 技术整合、统一结果封装、统一异常处理、前后联调、拦截器

    [前置内容]Spring 学习笔记全系列传送门: Spring学习笔记 - 第一章 - IoC(控制反转).IoC容器.Bean的实例化与生命周期.DI(依赖注入) Spring学习笔记 - 第二章 ...

  7. idea正则替换

    将非 (股权)的替换成 股权

  8. Java语言发展史-计算机进制转换

    Java语言发展史 java的诞生 在1991年时候,James Gosling在Sun公司的工程师小组想要设计这样一种主要用于像电视盒这样的消费类电子产品的小型计算机语言. 这些电子产品有一个共同的 ...

  9. 【学习笔记】C/C++ 设计模式 - 工厂模式(下)

    介绍说明 这篇笔记承接<[学习笔记]C/C++ 设计模式 - 工厂模式(上)>文章,主要记录 "抽象工厂设计模式" 的学习笔记,上一次是以音频播放器来作为例子,主要是想 ...

  10. 论文翻译:2022_Phase-Aware Deep Speech Enhancement: It’s All About The Frame Length

    摘要 虽然相位感知语音处理近年来受到越来越多的关注,但大多数帧长约为32 ms的窄带STFT方法显示出相位对整体性能的影响相当温和.与此同时,现代基于深度神经网络(DNN)的方法,如Conv-TasN ...