直接比对 composer.lock 文件最准确,因其精确记录版本、dist.shasum、源 url 和 require 关系,不受终端宽度、排序或 ansi 颜色干扰;推荐用 diff 聚焦 name/version/dist 字段,或使用 composer-lock-diff 输出语义化变更,并确保 platform 配置一致、脚本执行完整。

直接比对 composer.lock 文件是最准的
别折腾 composer show 或树形输出,那些受终端宽度、排序、ANSI 颜色干扰,diff 出来全是假变化。真正反映安装行为的只有 composer.lock —— 它精确记录每个包的版本、dist.shasum、源 URL、require 关系,且不依赖 vendor/ 目录是否存在。
实操建议:
- 从生产环境安全导出当前
composer.lock,重命名为composer.lock.prod - 本地确保已执行
composer update --lock(不是install),让本地composer.lock是最新解析结果 - 用
diff -u composer.lock composer.lock.prod | grep "^\([+-]\|\"name\"\|\"version\"\|\"dist\"\)"聚焦关键字段:增删包、版本变动、哈希变化 - 注意:若两边
composer.json中config.platform不一致(如 PHP 版本不同),lock会系统性差异,先对齐再比
用 composer-lock-diff 看人类可读变更
它专为这个场景设计,不解析 JSON,直接读 lock 文件结构,输出「新增」「删除」「升级」「降级」四类变更,并标出是否影响 autoload(比如 psr-4 映射改了)。
实操建议:
- 全局安装:
composer global require clue/composer-lock-diff,并确保~/.composer/vendor/bin在$PATH中 - 备份旧 lock:
cp composer.lock composer.lock.bak,再运行composer update - 执行:
composer-lock-diff composer.lock.bak composer.lock - CI 场景下可直接从 Git 历史读取:
git show HEAD~1:composer.lock | composer-lock-diff - composer.lock
用 JSON + jq 生成稳定可复现快照
composer show --locked --format=json 输出的是纯数据源,但默认键序不固定;加 jq -S 强制排序后,两次导出结构完全一致,diff 才可靠。
实操建议:
- 导出前先确认本地和目标环境都已运行
composer update --lock,避免缓存或未提交修改污染基线 - 执行:
composer show --locked --format=json | jq -S . > lock.before.json - 更新后:
composer show --locked --format=json | jq -S . > lock.after.json - 比对:
diff lock.before.json lock.after.json - 切记不要用
composer show不带--locked,它读的是当前vendor/状态,可能混入require-dev包或本地pathrepo
警惕 --no-scripts 导致的“假一致”
很多部署流程加了 --no-scripts 来提速,这会让 post-install-cmd 类钩子(如生成 autoload.php、刷新 APCu 缓存)跳过执行。此时 vendor/ 内容虽与 composer.lock 匹配,但运行时仍可能失败——比如 Class not found 或缓存未更新。
实操建议:
- 比对
lock只是第一步,必须验证脚本是否真实执行过 - 检查生产环境是否用了
composer install --no-scripts --no-dev,而本地没加这些参数 - 若无法登录生产环境,可用
composer install --dry-run --no-dev模拟,再结合composer show --tree推断实际加载路径 - 特别关注
autoload字段变化:哪怕版本没动,如果psr-4映射路径改了,vendor/autoload.php就得重建
比对本身不难,难的是确保两边 lock 文件代表的是同等约束条件下的真实快照——平台配置、dev 依赖开关、脚本执行状态,任何一个不一致,都会让 diff 结果失去意义。











