--- name: pnpm-patches description: 直接对第三方包进行定制化补丁修改 --- # pnpm 补丁 pnpm 的补丁功能让你可以直接修改第三方包。在官方版本发布前应用修复,或定制包的行为,都非常有用。 ## 创建补丁 ### 步骤 1:初始化补丁 ```bash pnpm patch <包名>@<版本> # 示例 pnpm patch express@4.18.2 ``` 这会创建一个包含该包源码的临时目录,并输出路径: ``` You can now edit the following folder: /tmp/abc123... ``` ### 步骤 2:编辑文件 进入临时目录并进行修改: ```bash cd /tmp/abc123... # 根据需要编辑文件 ``` ### 步骤 3:提交补丁 ```bash pnpm patch-commit <步骤1中的路径> # 示例 pnpm patch-commit /tmp/abc123... ``` 这会在 `patches/` 目录下生成一个 `.patch` 文件,并更新 `package.json`: ``` patches/ └── express@4.18.2.patch ``` ```json { "pnpm": { "patchedDependencies": { "express@4.18.2": "patches/express@4.18.2.patch" } } } ``` ## 补丁文件格式 补丁使用标准的统一差异格式(unified diff): ```diff diff --git a/lib/router/index.js b/lib/router/index.js index abc123..def456 100644 --- a/lib/router/index.js +++ b/lib/router/index.js @@ -100,6 +100,7 @@ function createRouter() { // 原始代码 - const timeout = 30000; + const timeout = 60000; // 延长超时时间 return router; } ``` ## 管理补丁 ### 列出已补丁的包 ```bash pnpm list --depth=0 # 已打补丁的包会显示 (patched) 标记 ``` ### 更新补丁 ```bash # 编辑已有补丁 pnpm patch express@4.18.2 # 编辑完成后 pnpm patch-commit <路径> ``` ### 移除补丁 ```bash pnpm patch-remove <包名>@<版本> # 示例 pnpm patch-remove express@4.18.2 ``` 或者手动移除: 1. 从 `patches/` 目录删除补丁文件 2. 从 `package.json` 的 `patchedDependencies` 中移除对应条目 3. 运行 `pnpm install` ## 补丁配置 ### 自定义补丁目录 ```json { "pnpm": { "patchedDependencies": { "express@4.18.2": "custom-patches/my-express-fix.patch" } } } ``` ### 多个包 ```json { "pnpm": { "patchedDependencies": { "express@4.18.2": "patches/express@4.18.2.patch", "lodash@4.17.21": "patches/lodash@4.17.21.patch", "@types/node@20.10.0": "patches/@types__node@20.10.0.patch" } } } ``` ## 工作空间 补丁在整个工作空间内共享。在根目录的 `package.json` 中定义: ```json // 根目录 package.json { "pnpm": { "patchedDependencies": { "express@4.18.2": "patches/express@4.18.2.patch" } } } ``` 所有使用了 `express@4.18.2` 的工作空间包都会应用该补丁。 ## 最佳实践 1. **版本精确性**:补丁与精确版本绑定。升级依赖时请同步更新补丁。 2. **记录补丁**:添加注释说明补丁存在的原因: ```bash # 在 patches/README.md 中 ## express@4.18.2.patch 修复超时问题。待合入 PR:https://github.com/expressjs/express/pull/1234 ``` 3. **精简补丁**:保持补丁短小精悍。过大的补丁难以维护。 4. **跟踪上游**:记录上游的 issue/PR,以便在问题修复后移除补丁。 5. **测试补丁**:确保补丁后的代码在你的使用场景中正常工作。 ## 故障排查 ### 补丁应用失败 ``` ERR_PNPM_PATCH_FAILED Cannot apply patch ``` 包版本发生了变化。重新创建补丁: ```bash pnpm patch-remove express@4.18.2 pnpm patch express@4.18.2 # 重新应用修改 pnpm patch-commit <路径> ``` ### 补丁未生效 请确认: 1. `patchedDependencies` 中的版本与已安装版本完全一致 2. 添加补丁配置后运行了 `pnpm install`