源码补丁神器—patch-package

一、背景

vue项目中使用 vue-pdf 第三方插件预览pdf,书写业务代码完美运行,pdf文件内容正常预览无问题。后期需求有变,业务需求增加电子签章功能。这个时候pdf文件的内容可以显示出来,但是公司的电子签章无法显示。这令人沮丧,因为已经编写了许多特定于此依赖项的代码,如果替换依赖库,这些代码很可能会被浪费。更重要的是其已经在生产环境运行。

在不更改依赖库进行大改动的前提下,先查找问题所在。经查发现此为官方bug 无法显示签章。进一步查询发现根源是其依赖包 pdf.js电子签章不显示

问题已定位到,要修改显示电子签章的代码是在node_modules的依赖包中。

如何解决此问题?

二、常用方法

  1. 给依赖包提 issue 等待他人修复并发布

  2. 给依赖包提 pr 自行修复并等待发布

  3. 整体copy项目法

直接引用法

直接copy依赖包的源码,本地引用,不再通过npm包方式引用

发布私库法

适合多项目中使用同一个依赖包的场景,可以把修改后的源码发布到私有的仓库上

  1. 修改引用法

配置一个webpack alias别名,如'原始文件的引用路径': '修改后文件的引用路径',使得最终修改后的文件被引用,如:

css 复制代码
resolve: {  
    alias: {  
        'pdfjs': path.resolve(__dirname, './patched/pdfjs/*'), 
    }
}

以上方法均有弊端:

前两种修复周期很长且依赖第三方,修复时间不定,不适合解决当前问题。

后几种方法都比较复杂,并且会导致项目臃肿,更容易忘记自己修改了源码的哪个部分,而且更新麻烦,每次都需要手动去更新代码,无法与插件同步更新。

有没有一种方法,可以优雅修改node_modules的源码?

三、patch-package

patch-package 让程序开发者立即修复并保留 npm 依赖项。是一个给依赖项打补丁的完美方案。

perl 复制代码
# fix a bug in one of your dependencies
vim node_modules/some-package/brokenFile.js

# run patch-package to create a .patch file
npx patch-package some-package

# commit the patch file to share the fix with your team
git add patches/some-package+3.14.15.patch
git commit -m "fix brokenFile.js in some-package"

使用方法:

1.安装

css 复制代码
npm i patch-package

如果你不需要在生产中运行

css 复制代码
npm i patch-package --save-dev

yarn、pnpm、docker安装命令可查看其 git官网。

  1. 修改npm包

更改node_modules 文件夹中要修改依赖包的文件

  1. 生成补丁

npx patch-package package-name

  1. 添加自动执行命令

In package.json

json 复制代码
 "scripts": {
    +  "postinstall": "patch-package"
 }

在本文示例中,在node_modules找到要修改的依赖包pdfjs-dist,修改代码如下:

执行npx patch-package pdfjs-dist,生成补丁,会在文件目录中生成一个patches文件夹,如下:

至此项目中的bug已修复,如何让更改内容在团队其他同事拉取代码后执行?

添加自执行命令如下,会在 npm install 后知执行。

patch文件是什么?

其实就是一些git diff记录描述。

原理: patch-package会将当前 node_modules下的源码与原始源码进行 git diff,并在项目根目录下生成一个patch补丁文件。

如何自测补丁是否生效?

手动删除项目中的node_modules,并重新执行npm install命令安装依赖包。安装成功后查看之前修改的 node_modules 依赖包中的文件,查看修改的代码是否依然存在,如果之前修改代码依然存在即表明补丁文件已经生效,如果你之前修改的代码不存在即表明补丁文件没有生效。

四、patch-package 好处

版本预检

当依赖项发生更改时,会以红色大写字母通知,需要检查所做修复是否仍然有效。npx patch-package 会直接报错**ERROR** Failed to apply patch for package xxxx at path,通过提示可以更方便定位问题。

节省空间

无需拷贝一份源码,使用git diff来记录补丁更节省空间,安全又便捷。

可审查

补丁可以作为正常审查过程的一部分进行审查。

五、注意事项

◦直接修改 node_modules 下的代码不是被推荐的做法,应该仅在应急情况下考虑

◦长期还是需要彻底修复第三方包缺陷并逐步移除项目中的 .patch 文件

作者:京东保险 张洁

来源:京东云开发者社区 转载请注明来源

相关推荐
爱笑的源码基地10 小时前
智慧班牌源码:从后端SpringBoot到前端Vue2的全栈实现
java·大数据·云计算·源码·程序代码·智慧校园源码·智慧班牌源码
源码宝1 天前
MES系统源码:Java8 + SpringBoot2.7 + MySQL8 + Redis,后端源码清爽易扩展
java·后端·源码·springboot·mes系统·源码二开·mes源码
魏思凡1 天前
Glide 源码学习系列
源码·glide
谷哥的小弟2 天前
图文详解Spring Boot整合MyBatisPlus(附源码)
mybatis·源码·springboot·mybatis-plus·整合
万岳科技程序员小金4 天前
真人数字人系统源码开发指南:一套平台如何支撑多端应用(APP/小程序)
源码·软件开发·ai数字人小程序·ai数字人系统源码·ai真人数字人app开发·数字人平台搭建
工业互联网专业5 天前
国潮男装微博评论数据分析系统的设计与实现 _flask+spider
python·flask·毕业设计·源码·课程设计·spider
大叔_爱编程5 天前
基于职业能力的知识图谱的学习路径推荐系统_django
django·毕业设计·源码·知识图谱·课程设计
元思未来7 天前
Hermes Agent 源码探秘 (5):System Prompt 组装 — Agent 的"灵魂"
源码·agent
淘源码d8 天前
产科系统源码,数字产科源码,Java(后端) + Vue + ElementUI(前端) + MySQL(数据库),确保系统稳定性与扩展性。
java·源码·数字产科·产科系统·智能化孕产服务·高危五色预警·智慧产科
爱笑的源码基地10 天前
小微企业ERP源码,采用SpringBoot+Vue+ElementUI+UniAPP技术架构,支持二次开发及商用授权
java·源码·二次开发·erp·源代码·mrp生产计划