Composer install 默认会覆盖 vendor 中的手动 patch,需用 composer-patches 插件声明式管理;配置 "patches-ignore": false 可使 patch 失败时中断流程,避免静默失效。

Composer install 会覆盖 vendor 中的 patch 修改
默认情况下,composer install 会完全重装 vendor/ 目录下的包,任何手动打在源码上的 patch(比如改了某行逻辑、加了调试日志)都会被清掉。这不是 bug,是设计使然——Composer 假设 vendor 是可完全重建的“只读”产物。
用 composer-patches 插件管理 patch 才能持久化
靠手动改 vendor 文件不是办法,必须把 patch 变成声明式配置。主流方案是使用 composer-patches 插件,它会在 install 和 update 后自动重打 patch。
- 先安装插件:
composer require cweagans/composer-patches - 在
composer.json的"extra"字段中声明 patch,例如:
"extra": {
"patches": {
"drupal/core": {
"Fix broken cache tag invalidation": "patches/core-fix-cache-tags.patch"
}
}
}
注意:patch 文件路径是相对于 composer.json 的,且必须是 git-format patch(可用 git diff > xxx.patch 生成)。
patch 失败时 Composer 不会中断 install,但会报 warning
composer-patches 默认失败不终止流程,只会输出 Warning: Patch ... failed to apply。这容易让人误以为成功了,实际代码没改。
- 加
"patches-ignore": false到extra可让失败变 fatal(推荐) - 确保 patch 是基于目标包的正确版本生成的——比如给
monolog/monolog:2.10.0打的 patch,不能直接用在2.11.0上,行号偏移会导致失败 - 如果 patch 涉及多文件或重命名,用
git apply --3way更健壮,可在插件配置里启用"apply_patch": true并配合git环境
开发阶段临时绕过 patch 验证?别用 --no-scripts
有人想跳过 patch 应用阶段,试过 composer install --no-scripts,但这会同时禁掉所有 post-install-cmd,包括 autoload 生成等关键步骤,反而导致后续运行报错。
- 真要跳过 patch:删掉
extra.patches或临时注释掉,而不是关 scripts - 调试 patch 本身:运行
composer run-script post-install-cmd单独触发 patch 应用,比重跑整个 install 快 - CI 环境建议始终开启
"patches-ignore": false,避免因 patch 失效而静默降级功能
patch 文件本身容易被忽略进 .gitignore,或者放错路径导致本地能跑 CI 上失败——检查 ls -l patches/ 和 composer validate 输出里的 patch 路径提示最直接。


















