composer.lock不是可选文件,而是部署强制契约;它精确锁定版本、commit hash和SHA256校验值,使composer install完全忽略composer.json的范围约束,确保环境一致、构建可重现。

composer.lock 不是缓存,是部署契约——没它,composer install 就不成立。
composer.lock 为什么不是可选文件?
它记录的是精确版本、Git commit hash、dist 包的 sha256 校验值,三者缺一不可。只要 composer.lock 存在,composer install 就完全忽略 composer.json 里的 ^2.9 或 ~3.1 这类范围约束,只认锁文件里写的 "version": "2.9.1"。
- 删掉
composer.lock后执行composer install,等价于隐式运行composer update,结果不可控 - CI/CD 流水线中缺失该文件,会导致不同构建节点装出不同
vendor/,典型报错:Class not found或The lock file does not contain the required package "xxx" - 应用型项目(Laravel、Symfony、CLI 工具)必须提交
composer.lock到 Git;库项目(供别人require的包)则禁止提交
哪些操作会改变 composer.lock 并需要提交?
只有真正影响依赖树的操作才需同步更新并提交 composer.lock:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 修改
composer.json中的require或require-dev - 调整
platform(如"php": "8.2.15")、minimum-stability或prefer-stable - 运行
composer update、composer require或composer remove - 改
scripts、name、description等字段,不碰composer.lock
并发部署时 composer.lock 为什么会失效?
composer install 本身不加锁,也不校验写入状态。多个进程同时读取同一份 composer.lock,各自解析、下载、写入 vendor/,但没人管“别人是不是也在改”。后果包括:
- 部分包漏装(一个进程装了
symfony/http-client,另一个没装) -
vendor/半途而废(CI 超时 kill 后,composer.lock还在,下次install可能跳过require-dev) -
content-hash没变但packages数组顺序错乱(Git 自动换行或编辑器格式化导致 JSON 结构不一致)
必须用 flock ./composer.lock -c 'composer install --no-interaction' 串行化,且禁止在 CI 中自动跑 composer update —— 它重写 composer.lock 时不校验是否已被他人修改,多进程并发等于多人同时重画一张地图。

















