patch-package修改依赖包

# 背景

# 如何优雅的修改node_modules中的依赖库

方法一:把修改后的代码换个名字重新打个包提交到tnpm,然后直接引用这个新包

方法二:把代码copy移出node_modules作为本地依赖

无论是上面哪种办法,作为有代码洁癖的人来说,都觉得很别扭,我就改了某一个文件了一两行代码,却要如此臃肿的copy整个项目,更要命的是最后可能都忘了自己修改了哪里,没有diff可供追溯。

# np不支持github发布

  • np本身是不支持githubpackage包的发布的,所以我们还需要修改其源码,找到np下的source\prerequisite-tasks.js将第32行verify user is authenticated到第54行给注释掉。这样就可以支持githubpackage包的发布了。喜欢折腾的可以试试用patch-package;
  • 用了第三方库,但是在使用中发现了该包中的一个bug。在debug的过程中直接修复了该漏洞,并向该项目提了PR,作者也很快做出了反应。因为该项目疑似已不再维护,代码被合并后作者也未发布新版本。因为后续功能的开发受该bug的影响,只能采用修改内容创建补丁的方式修复bug。

本文中创建补丁的方式为使用了patch-package (opens new window)

步骤总括

  • 本地安装,npm i patch-package
  • 修改node_modules中的代码; 找到np下的source\prerequisite-tasks.js将第32行verify user is authenticated到第54行给注释掉。样就可以支持githubpackage包的发布了
  • 生成patches,npx patch-package np
  • 在package.json 的scripts中加入 { "postinstall": "patch-package" },这是npm的一个钩子,会在依赖包被install之后执行
  • 提交patches后,重新install包你就会发现是你修改后的结果 npm install

# 安装patch-package

patch-package包可以通过npm进行安装。

npm i patch-package --save-dev
1

或者也可以通过yarn进行安装。

yarn add --dev patch-package postinstall-postinstall
1

# 创建补丁

在修改依赖包内容后,就可以运行patch-package创建patch文件了。

$ npx patch-package package-name   # 使用npm
$ yarn patch-package package-name  # 使用yarn
1
2

运行后通常会在项目根目录下的patches目录中创建一个名为package-name+version.patch的文件。将该patch文件提交至版本控制中,即可在之后应用该补丁了。

# 部署

完成上述操作后,最后还需要修改package.json的内容,在scripts中加入"postinstall": "patch-package"

"scripts": {
  "postinstall": "patch-package"
}
1
2
3

至此,在后续运行npm install或是yarn install命令时,便会自动为依赖包打上我们编写的补丁

np+6.4.0.patch

diff --git a/node_modules/np/source/prerequisite-tasks.js b/node_modules/np/source/prerequisite-tasks.js
index 211ba97..2109b20 100644
--- a/node_modules/np/source/prerequisite-tasks.js
+++ b/node_modules/np/source/prerequisite-tasks.js
@@ -28,30 +28,30 @@ module.exports = (input, pkg, options) => {
 				version.verifyRequirementSatisfied('yarn', yarnVersion);
 			}
 		},
-		{
-			title: 'Verify user is authenticated',
-			skip: () => process.env.NODE_ENV === 'test' || pkg.private,
-			task: async () => {
-				const username = await npm.username({
-					externalRegistry: isExternalRegistry ? pkg.publishConfig.registry : false
-				});
+		// {
+		// 	title: 'Verify user is authenticated',
+		// 	skip: () => process.env.NODE_ENV === 'test' || pkg.private,
+		// 	task: async () => {
+		// 		const username = await npm.username({
+		// 			externalRegistry: isExternalRegistry ? pkg.publishConfig.registry : false
+		// 		});
 
-				const collaborators = await npm.collaborators(pkg);
-				if (!collaborators) {
-					return;
-				}
+		// 		const collaborators = await npm.collaborators(pkg);
+		// 		if (!collaborators) {
+		// 			return;
+		// 		}
 
-				const json = JSON.parse(collaborators);
-				const permissions = json[username];
-				if (!permissions || !permissions.includes('write')) {
-					throw new Error('You do not have write permissions required to publish this package.');
-				}
-			}
-		},
-		{
-			title: 'Check git version',
-			task: async () => git.verifyRecentGitVersion()
-		},
+		// 		const json = JSON.parse(collaborators);
+		// 		const permissions = json[username];
+		// 		if (!permissions || !permissions.includes('write')) {
+		// 			throw new Error('You do not have write permissions required to publish this package.');
+		// 		}
+		// 	}
+		// },
+		// {
+		// 	title: 'Check git version',
+		// 	task: async () => git.verifyRecentGitVersion()
+		// },
 		{
 			title: 'Check git remote',
 			task: async () => git.verifyRemoteIsValid()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
上次更新: 2022/04/15, 05:41:27
×