分支交叉开发时,依赖包的“开发版”由 composer.json 与 composer.lock 共同锁定;composer install 严格按 lock 文件安装确保环境一致,而 composer update 会重算依赖树、覆盖 lock 文件,导致多分支间 vendor 不一致,引发 class not found 等隐性问题。

分支交叉开发时,依赖包的“开发版”不是靠分支名决定的,而是由 composer.json + composer.lock 的当前状态共同锁定;清理必须以 lock 文件为基准,不能只看分支 diff。
composer install 和 composer update 在多分支中行为差异极大
你在 feature/login 分支运行过 composer update,而 main 分支仍停留在旧的 composer.lock,这时两个分支的 vendor 实际内容就已不一致——哪怕 composer.json 完全相同。
这种不一致不会在 git diff 里体现,但会导致「在我分支能跑,切回 main 就报 Class not found」。
-
composer install只读composer.lock,无视composer.json中的版本约束,确保环境可重现 -
composer update强制重算依赖树,覆盖composer.lock,会把其他分支没 merge 进来的变更也拉进来 - CICD 流水线里若混用这两个命令(比如先
install再update),极易引入隐性漂移
如何判断当前分支的“开发版”实际指向哪个包版本
别信分支名或 commit message,直接查 composer.lock 里的哈希和 source url:
- 运行
composer show vendor/package-name,看输出中的 version 字段是否带-dev或dev-前缀(如dev-main、dev-feature/auth) - 检查
composer.lock中该包的source字段:"type": "git"且"reference"是短哈希,说明是 dev 版本直连仓库 - 若
dist字段存在且url指向 packagist.org 的 tarball,则是稳定发布版
注意:Laravel 或 Symfony 项目中,有些包(如 laravel/sail)默认启用 prefer-stable: true,即使你 require 了 dev-main,它也可能 fallback 到最近 stable tag。
交叉开发后如何安全清理 dev 版依赖残留
merge 完 feature 分支后,常出现 vendor 里还留着 dev-feature/xxx 的代码,但 composer.lock 已切回 stable —— 这不是 bug,是 Composer 不主动删“未声明包”的设计逻辑。
- 先运行
composer install --no-dev(生产环境)或composer install(开发环境),强制按 lock 文件重建 vendor - 如果仍有残留,说明该包被其他已安装包硬依赖(例如
spatie/laravel-ray依赖spatie/backtrace的 dev 版),用composer depends spatie/backtrace查来源 - 手动删
vendor/spatie/backtrace后再composer dump-autoload,否则 autoload 映射仍可能命中旧路径 - CI 环境建议加
--no-cache参数:composer install --no-cache --no-dev,跳过本地缓存干扰
为什么不能靠 git clean -fdx vendor 清理
直接 rm -rf vendor 或 git clean 会绕过 Composer 的 autoload 重建逻辑,尤其当项目启用了 --classmap-authoritative 或自定义 autoload.files 时,后续 composer install 可能无法恢复 classmap 条目。
- 正确做法是:删前先确认
composer.lock已同步目标分支状态,再执行composer install - 若 vendor 已损坏(比如部分目录权限异常),用
composer install --no-cache比rm -rf vendor && composer install更可靠 - 某些私有包使用 path repository,
vendor下是 symlink,git clean会误删源目录,风险极高
最易被忽略的一点:Composer 不管理 config/、app/Providers/ 或 .env 中对包的引用。dev 版包卸载后,这些地方的手动配置必须人工核对,否则 runtime 错误不会在 composer install 阶段暴露。











