composer.lock必须在依赖树固化后立即生成,它精确记录vendor目录内容,仅在composer install(无lock时)、update或require/remove时写入;需验证tree收敛、dist shasum完整且vendor与lock时间对齐。

composer.lock 必须在依赖树固化后立即生成
你运行 composer install 或 composer update 后,vendor/ 目录里装了什么,只有 composer.lock 能精确记录。但很多人误以为“只要跑过 install 就算固化”,其实不是——如果没生成或没提交 lock 文件,那这次安装就是一次临时快照,随时可能被覆盖或丢失。
关键点在于:lock 文件不是“自动生成”的,它只在以下情况被写入:
-
composer install时,若当前无composer.lock,会先按composer.json解析依赖、计算完整树、下载并写入 lock; -
composer update时,无论有没有 lock,都会重新解析整个依赖树、更新所有包(含间接依赖),然后重写 lock; -
composer require或composer remove也会触发 lock 更新。
所以“依赖树固化”动作本身,就是执行一次确定性的 composer update 或 composer install,并确保输出的 composer.lock 已落地、未被修改、且已纳入备份范围。
用 composer tree --format=tree 验证依赖树是否收敛
composer tree 不是备份操作,但它是判断“当前依赖是否真正稳定”的最直接手段。如果你刚跑完 composer update,却没验证结果,就直接打包备份,很可能锁住的是一个尚未收敛的中间态。
执行前确认两点:
- 必须使用 Composer 2.5+(旧版本不支持
--format=tree); - 确保当前
vendor/是由本次composer.lock安装而来(不是手动 cp 过来的、也不是上个分支残留的)。
验证命令:
composer tree --format=tree --no-dev
观察输出中是否有警告行(如 Warning: Package ... is abandoned)、重复包名不同版本共存、或出现 [dev-xxx] 这类非稳定标识——这些都意味着依赖树还没真正“收口”,不适合进入备份流程。
私有包和 dist shasum 必须出现在 lock 文件里才算固化成功
composer.lock 里每项依赖都应包含 dist 字段,其中 shasum 是校验关键。缺失它,等于没锁死二进制内容——下次 install 可能拉到被篡改或替换成镜像源缓存的脏包。
检查方法(以 monolog/monolog 为例):
grep -A 5 '"monolog/monolog"' composer.lock | grep shasum
正常应输出类似:"shasum": "a1b2c3d4e5f67890..."。如果为空、为 null、或整块 dist 段缺失,说明该包是通过 source 方式安装(比如 Git clone),其 commit hash 虽在 lock 中,但网络不可达时无法复原。
应对方式:
- 对私有 Git 包,强制走 dist:在
composer.json的repositories中加"type": "package"+"dist"描述,或使用composer config --global github-protocols https统一协议; - 离线场景下,必须配合
composer archive打 zip,不能只靠 lock 文件。
备份前删 vendor/ 会导致 lock 文件失效
这是最容易被忽略的操作陷阱:有人觉得“备份前清掉 vendor/ 更干净”,结果 composer archive 或后续 composer install 报错找不到包,或打出来的 zip 是空的。
原因很简单:composer archive 和 composer install --no-dev 都依赖当前 vendor/ 目录的文件存在性来读取包元数据、校验路径、提取自动加载映射。它不从 lock 文件“凭空还原”,而是基于已安装状态做打包或校验。
正确顺序只能是:
- 先确保
vendor/是由当前composer.lock安装的(可对比composer show --installed | head -5和 lock 文件前几项); - 再运行
composer archive --format=zip --dir=backup/ myapp-$(date +%Y%m%d).zip; - 最后才清理 vendor/(如果磁盘紧张)。
lock 文件和 vendor/ 必须时间对齐,差一秒都可能导致 RPO(恢复点目标)失控。











