想想我们在使用第三方依赖包时如果遇到了bug,通常解决的方式都是绕过这个问题,使用其他方式解决,较为麻烦。或者给作者提个issue,然后等待作者的修复,等待的时间不可控。那么这时候就可以借助patch-package自己动手去修复该bug,感觉是不是很棒,并且还可以在第三方依赖包上,根据业务需求扩展能力。
当然最好还是扩展一些通用性比较高的能力,如果是比较通用且该能力大多数开发者都有这种诉求的话可以给第三方依赖包提个PR。参与开源项目是不是简单了起来了~(不要在魔改的路上越走越远)
使用步骤
Step1: 安装
// 使用npm安装
npm i patch-package
// 使用yarn安装
yarn add patch-package postinstall-postinstall
为什么要使用yarn安装,需要多安装postinstall-postinstall这个依赖,有兴趣可以看官方解释 Why use postinstall-postinstall
Step2:修改package.json
package.json的scripts中声明了一系列的npm脚本命令,如下:(参考资料:npm-scripts)
- prepublish: 在包发布之前运行,也会在npm install安装到本地时运行
- publish,postpublish: 包被发布之后运行
- preinstall: 包被安装前运行
- install,postinstall: 包被安装后运行
- preuninstall,uninstall: 包被卸载前运行
- postuninstall: 包被卸载后运行
- preversion: bump包版本前运行
- postversion: bump包版本后运行
- pretest,test,posttest: 通过npm test命令运行
- prestop,stop,poststop: 通过npm stop命令运行
- prestart,start,poststart: 通过npm start命令运行
- prerestart,restart,postrestart: 通过npm restart运行
可以看到依赖包在安装完之后会执行postinstall命令
所以我们在package.json的scripts里面增加:"postinstall": "patch-package"
"scripts": {
***,
+ "postinstall": "patch-package"
}
Step3:修改依赖包源码
在项目的node_modules 找到要修改的依赖包, 例如(resize-observer-polyfill):
Step4: 生成补丁
yarn patch-package package-name(修改的包名)
或者
npx patch-package package-name(npm版本 > 5.2)
patch-package 6.4.7
• Creating temporary folder
• Installing [email protected] with yarn
• Diffing your files with clean files
✔ Created file patches/resize-observer-polyfill+1.5.1.patch
resize-observer-polyfill is on GitHub! To draft an issue based on your patch run
yarn patch-package resize-observer-polyfill --create-issue
可以看到patch-package已经为我们创建了一个补丁。
默认会在我们的根目录下创建一个patches文件夹。在patches文件夹下会创建依赖包名+版本号.patch的文件,文件描述了我们修改了什么,第几行,有点像git的提交记录
Step5: 测试补丁是否有效
手动删除node_modules文件夹,重新执行npm install安装依赖包。可以看到在依赖包安装结束后执行了patch-package命令,之前生成的补丁被应用了
patch-package 6.4.7
Applying patches...
[email protected] ✔
Done in 177.35s.
查看node-modules中之前修改的resize-observer-polyfill 修改的地方,查看之前修改的代码是否还存在。如果之前修改的代码还存在,说明补丁文件已经生效了,如果不存在,排查下是否哪个步骤出现了问题。
最后将patches文件夹推送到远端仓库,日后无论是谁拉取代码,安装依赖,我们之前修改的部分都会生效的
注意事项
patch是锁定版本号的,如果升级了版本,patch内容将会失效,最好在package.json能够锁定版本号。
魔改的同时,也局限了升级的能力,尽量还是去提issue和PR。