如何“优雅”地修改 node_modules 下的代码?
在实际开发过程中当我们遇到 node_modules
中的 A 包有 bug 时候,通常开发者有几个选择:
方法一:给 A 包提 issue 等待他人修复并发布:做好石沉大海或修复周期很长的准备。
方法二:给 A 包提 mr 自行修复并等待发布:很棒,不过你最好祈祷作者发版积极,并且新版本向下兼容。
方法三:把 A 包的源码拖出来自己维护:有点暴力且事后维护成本较高,不过应急时也能勉强接受。
等等,可如果出问题的包是“幽灵依赖”呢,比如项目的依赖链是: A -> B -> C,此时 C 包有 bug。那么上面三个方法的改动需要同时影响到 A、B、C 三个包,修复周期可能就更长了,可是你今晚就要上线啊,这可怎么办?
上线要紧,直接手动修改 node_modules
下的代码给缺陷包打个临时补丁吧,可问题又来了,改动只能在本地生效,构建却在云端, 积极的同学开始写起了脚本,然后陷入一个个坑里...
上述场景下即可考虑使用 patch-package 这个包,假设我们现在的源码结构如下所示:
├── node_modules
│ └── lodash
│ └── toString.js
├── src
│ └── app.js // 依赖 lodash 的 toString 方法
└── package.json
node_modules/lodash/toString.js
var baseToString = require('./_baseToString')
function toString(value) {
return value == null ? '' : baseToString(value);
}
module.exports = toString;
src/app.js
const toString = require('lodash/toString')
console.log(toString(123));
假设现在需要修改 node_modules/lodash/toString.js
文件,只需要遵循以下几步即可“优雅”完成修改:
第一步:安装依赖
yarn add patch-package postinstall-postinstall -D
第二步:修改 node_modules/lodash/toString.js
文件
function toString(value) {
console.log('it works!!!'); // 这里插入一行代码
return value == null ? '' : baseToString(value);
}
module.exports = toString;
第三步:生成修改文件
npx patch-package lodash
这一步运行后会生成 patches/lodash+4.17.21.patch
,目录结构变成下面这样:
├── node_modules
│ └── lodash
│ └── toString.js
├── patches
│ └── lodash+4.17.21.patch
├── src
│ └── app.js
└── package.json
其中 .patch 文件内容如下:
diff --git a/node_modules/lodash/toString.js b/node_modules/lodash/toString.js
index daaf681..8308e76 100644
--- a/node_modules/lodash/toString.js
+++ b/node_modules/lodash/toString.js
@@ -22,6 +22,7 @@ var baseToString = require('./_baseToString');
* // => '1,2,3'
*/
function toString(value) {
+ console.log('it works!!!');
return value == null ? '' : baseToString(value);
}
第四步:修改 package.json
文件
"scripts": {
+ "postinstall": "patch-package"
}
最后重装一下依赖,测试最终效果:
rm -rf node_modules
yarn
node ./src/app.js
// it works!!!
// 123
可以看到,即便重装依赖,我们对 node_modules
下代码的修改还是被 patch-package
还原并最终生效。
至此我们便完成一次临时打补丁的操作,不过这并非真正优雅的长久之计,长期看还是需要彻底修复第三方包缺陷并逐步移除项目中的 .patch
文件。
作者:王力国
链接:https://juejin.cn/post/7022252841116893215