y.y
Published on

使用 pnpm patch 修补包

使用 pnpm patch 修补包

本文翻译自 Scott Spence 的博客文章:Patching packages with pnpm patch

我目前正在研究将一个大型应用从 Svelte 4 升级到 Svelte 5。从4升级到5并没有我想象的那么困难,但我发现了一个与另一个 Svelte 包相关的问题,我可以通过修补来解决。

在过去,如果我需要修补一个包,我会使用 patch-package,我之前在使用 patch-package 修补包中详细介绍过。

使用 patch-package 的缺点是,需要先安装包,然后添加一个 postinstall 脚本来运行补丁。而在 pnpm 中,这个功能已经内置在包管理器中了。

使用 pnpm patch 修补包

操作相当简单,但我在初始命令之后有点迷失了。😅

要使用 pnpm 修补包,你首先需要指定要修补的包和版本。

比如说,我想修补 svead 包,在 <meta> 标签中添加一个 alt 属性。

已安装的版本是 0.0.4,所以我将在命令中使用这个版本:

pnpm patch svead@0.0.4

这会输出以下内容:

你现在可以编辑以下文件夹:/tmp/ff5c69981b5e3c7d541f32db5546a177

完成更改后,运行 "pnpm patch-commit '/tmp/ff5c69981b5e3c7d541f32db5546a177'"

这就是最初让我感到困惑的地方,因为我在项目中查找 tmp 文件夹,而不是在我的文件系统中查找。😅

无论如何,我发现最简单的方法是使用 VS Code 打开文件夹:

code /tmp/ff5c69981b5e3c7d541f32db5546a177

这会在 VS Code 中打开文件夹,然后我就可以编辑文件并提交更改。

所以,在这个示例中,我想在现有包中添加一个 alt 属性,我将添加以下代码:

  <meta property="og:url" content={url} />
  <meta property="og:type" content="website" />
  <meta property="og:title" content={title} />
  <meta property="og:description" content={description} />
  <meta property="og:image" content={image} />
+ <meta property="og:image:alt" content={description} />

然后,按照初始 patch 命令中的说明,我可以运行提交命令:

pnpm patch-commit '/tmp/ff5c69981b5e3c7d541f32db5546a177'

现在,安装了 svead 包的项目在其根目录下会有一个 patches 文件夹,其中包含补丁文件 svead+0.0.4.patch

快速查看一下,可以看到对包所做的更改:

diff --git a/components/head.svelte b/components/head.svelte
index e932bbf1ffa795c081292bc669640f75d434ebfc..a63aef8c4beab3aec901ffd6a07ace0e0db845d8 100644
--- a/components/head.svelte
+++ b/components/head.svelte
@@ -44,6 +44,7 @@ export let paymentPointer = ''; // Web Monetisation Payment pointer
 		<meta property="og:title" content={title} />
 		<meta property="og:description" content={description} />
 		<meta property="og:image" content={image} />
+		<meta property="og:image:alt" content={description} />
 	{/if}

package.json 中添加了一个带有 patchedDependencies 对象的 pnpm 部分。这里引用了补丁文件。

"pnpm": {
  "patchedDependencies": {
    "svead@0.0.4": "patches/svead@0.0.4.patch"
  }
}

现在我可以提交这些更改并继续我的工作了!🥳

patch-remove

如果 svead 包在将来更新了,我可以使用 patch-remove 命令来移除补丁:

pnpm patch-remove svead@0.0.4

如果我所做的更改仍然需要应用,那么我可以为新版本重复相同的过程。

结论

使用 pnpm 进行包修补消除了对 patch-packagepostinstall 脚本等额外工具的需求,并在安装过程中自动应用补丁。

这种方法不仅有助于提高可维护性,而且还能为复杂项目或 monorepos 提供更高效的开发工作流程。