pnpm 中无法使用 patch-package 打补丁
原文:https://lwebapp.com/zh/post/pnpm-patch-package
介绍
前端开发过程中,经常会遇到第三方开源库有 BUG 的情况,通常我们有以下处理方式
- 自己 fork 一份源码修改,修复完后就可以本地打包直接用了。如果你想分享你的研究成果给其他人,可以再传到 npm 仓库或者提交 PR 给源仓库。这种方式有个缺点,就是笔记难保持和官方库的同步。
- 等待库作者修复。这种方式不太靠谱,因为开源作者一般都会比较忙,你的需求可能不会排在前面。
有些小伙伴不知道,还有一种方案是给本地 npm 包打补丁。意思是你的项目在正常安装某个 npm 依赖的情况下,通过在项目里增加一个补丁文件,就可以将对这个 npm 包的修改持久保存到项目中。这样就能实现针对开源库的 bug 修复直接应用到项目中。
小编了解到有一个叫 patch-package 的开源库,可以轻松的做到给 node_modules 的库打补丁。接下来我们看看如何使用 patch-package ,以及使用过程中有什么问题。
如何使用 patch-package
参照官方的教程,简单几步即可快速给本地 npm 包打补丁。
- 从 node_modules 中找到 npm 依赖包的源码,修复依赖包中的错误
vim node_modules/my-package/common.js
- 运行 patch-package 创建一个 .patch 文件,.patch 文件可以自动被 npm 识别并应用
npx patch-package my-package
- 提交补丁文件就可以与您的团队共享修复了
git add patches/my-package+3.14.15.patch
git commit -m "fix common.js in my-package"
- 安装下依赖包
npm i -D patch-package
- 在 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脚本将修改后的文件复制到源码目录中覆盖掉源代码,实现修改代码的目的。
- 修改好node_modules中依赖包源码文件,复制到跟目录的
patches
目录下
vim node_modules/my-package/common.js
cp node_modules/my-package/common.js patches/my-package
- 在项目中新建一个脚本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));
}
- package.json 中新增一个postinstall命令指向我们的脚本
"scripts": {
"postinstall": "node scripts/postinstall.js"
}
总结
以上就是小编在一个使用pnpm包管理器的项目中实现给npm包打补丁的方案,如果您有更好的解决思路,欢迎分享出来。
参考
pnpm 中无法使用 patch-package 打补丁的更多相关文章
- 为什么多线程、junit 中无法使用spring 依赖注入?
为什么多线程.junit 中无法使用spring 依赖注入? 这个问题,其实体现了,我们对spring已依赖太深,以至于不想自己写实例了. 那么到底是为什么在多线程和junit单元测试中不能使用依赖注 ...
- Linux-学习patch命令打补丁,diff命令制作补丁(3)
patch:通过补丁文件,来对原文件打补丁 diff: 比较两个文件,然后生成一个补丁文件 1.patch用法 patch -p[剥离层级] <[补丁文件] 2.patch命令 ...
- java中不带package和带package的编译运行方式
Java中不带package的程序和带package的程序编译的方式是不同的. 一.不带package的程序建立个HelloWorld.java的文件,放入C:\,内容如下:public class ...
- block中无法使用C数组变量
在Objective-C的block中无法使用C数组,即使我们不对C数组做任何改变,编译的时候也会报错: #include <stdio.h> int main() { const cha ...
- 自坑实录 - Asp.net MVC中无法使用@Ajax.BeginForm问题解决
创建空的web项目,通过Nuget引用mvc组件来搭建空的MVC项目时, 在视图页面中无法使用@Ajax.BegForm来进行异步提交数据, 而新建默认的MVC模板项目却能够正常使用@Ajax.Beg ...
- model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转;解决的方法是用responsewrite(普通的字符响应)
model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转:解决的方法是用responsewrite
- Ruby中使用patch HTTP方法
Ruby中使用patch HTTP方法 如果使用patch,在后台可以看到只更新了改动的部分: Started PATCH "/ads/5/update" for ::1 at 2 ...
- CenterOS7中解决No package mysql-server available.
CenterOS7中解决No package mysql-server available. 1.使用yum install -y mysql-server报错如下: [root@heyong_jd ...
- 巧用svn create patch(打补丁)方案解决定制版需求
最近项目定制版越来越多,维护,同步代码非常费事.以前的思路如下图: 以前的svn目录结构如下图: 这样问题有2个: 若在一个定制包中修复了其他定制包也有的bug,同步更新其他包的代码时,非常费劲+机械 ...
- Java中import及package的用法
有些人写了一阵子 Java,可是对於 Java 的 package 跟 import 还是不 太了解很多人以為原始码 .java 档案中的 import 会让编译器把所 import 的程式通通写到编 ...
随机推荐
- 何为GUI???
1.GUI是什么–简介 GUI的全称为Graphical User Interface,图形化界面或图形用户接口,是指采用图形方式显示的计算机操作环境用户接口.与早期计算机使用的命令行界面相比,图形界 ...
- RocketMQ消息短暂而又精彩的一生
大家好,我是三友~~ 这篇文章我准备来聊一聊RocketMQ消息的一生. 不知你是否跟我一样,在使用RocketMQ的时候也有很多的疑惑: 消息是如何发送的,队列是如何选择的? 消息是如何存储的,是如 ...
- 解决Java.awt设计GUI程序时Label标签中文乱码解决(idea)
未修改时对话框里边无法显示Label的文本内容,显示的都是方框!网上都是Run--Edit Configurations--VM options:填入-Dfile.encoding=gbk 但是我实际 ...
- 记一下Mybatis Plus遇到的现象
使用Springboot+Mybaits plus,在Controller中直接调用Service中的方法,没有配置事务,就算是在Services上加了@Transactional也是没有事务的,可以 ...
- 手把手教大家写书写一个Mqtt网关
摘要:物联网是现在比较热门的软件领域,众多物联网厂商都有自己的物联网平台,而物联网平台其中一个核心的模块就是Mqtt网关. 本文分享自华为云社区<一文带你掌握物联网mqtt网关搭建背后的技术原理 ...
- 【随笔记】NDK 编译开源库 ffmpeg
一.下载源代码 wget http://ffmpeg.org/releases/ffmpeg-4.4.tar.gz tar -zxvf ffmpeg-4.4.tar.gz 二.编译配置脚本 #! /b ...
- python生成自动化测试报告并发送到指定邮箱
#-*-coding:utf-8 -*- import HTMLTestRunner import unittest import time import sys import os import s ...
- C# 处理实体类赋值(获取嵌套类型,支持list 自定义类型)
public static T AESEncrypt<T>(T obj) where T : class { if (obj == null) { return obj; } var pr ...
- 【学习日志】MySQL分表与索引的关系
什么情况下需要分表呢?分表又能解决什么问题呢? 一般情况下分表的直接原因是数据量太大了,比如一张表一共只有1w条数据,确实没必要分表.为什么数据量大了就需要分表呢?首先得看看数量量过大后会带来什么问题 ...
- Solon2 开发之容器,八、动态代理的本质
在 Java 里动态代理,主要分:接口动态代理 和 类动态代理.因为它的代理类都是动态创建的,所以名字里会带上"动态". 官网的有些地方叫"代理",也有些地方叫 ...