sort-packages 不是运行时功能,仅在 composer require 或 update 修改 composer.json 时重排 require 和 require-dev 的键序;install 不触发,且对其他字段无效。

sort-packages 不是运行时功能,它只在 composer require 或 composer update 修改 composer.json 时重排 require 和 require-dev 的键顺序,composer install 完全不触发它。
为什么开了 sort-packages 却没看到 composer.json 变化
常见错误现象:"config": {"sort-packages": true} 已写入,但执行 composer install 后依赖块顺序依旧杂乱。
-
composer install只读composer.lock,不修改也不重排composer.json,所以永远不触发排序 - 即使配置开启,也要靠
composer require(加新包)或composer update(更新版本并导致composer.json被重写)才能生效 - 如果所有依赖都已锁定、无版本变更,
composer update可能跳过写入composer.json,也就不会重排 - 该配置对
autoload、scripts、config、extra等其他字段完全无效
怎么正确启用 sort-packages 并确认它在工作
使用场景:统一团队 composer.json 格式,减少 Git diff 噪音;CI 中校验依赖声明一致性。
- 在项目根目录的
composer.json顶层添加:"sort-packages": true(注意:必须是布尔值true,不能是字符串"true"或数字1) - 无需插件、无需全局配置,Composer 1.0.0+ 原生支持
- 验证是否生效:运行
composer require phpunit/phpunit --dev,观察新包是否按字母序插入到require-dev区块中 - 若已有依赖未排序,单次操作只影响新增/更新项;要全量重排,可临时清空
require,再逐个composer require回来(生产环境慎用)
sort-packages 的排序规则和容易踩的坑
排序依据是包名(vendor/name)的 ASCII 字符串顺序,不是版本号、别名或语义含义。
- 大小写敏感:
Symfony/flex(大写 S)会排在symfony/console(小写 s)前面,因为 ASCII 中S(83)s(115) - 下划线优先:
_my/package会排在所有字母开头的包之前(_ASCII 值为 95,小于A的 65) - 不处理注释或空行:原有注释不会随包移动,可能错位;建议搭配
composer normalize(需插件)做完整规范化 - 区块边界固定:
require和require-dev是独立排序的,不会跨区块合并或交换位置;你手写时把require-dev放require上面,它就永远在上面
真正麻烦的是半自动维护——手动改 + 自动排混用
最常出问题的不是配置本身,而是混合工作流:有人直接编辑 composer.json 添加包,又忘了跑 composer update;结果 Git 提交里全是键顺序变动,掩盖真实修改。
- 要么全交给 Composer 管(所有增删都走
composer require/composer remove) - 要么干脆关掉
sort-packages,避免“看起来规范、实际混乱”的假象 -
composer remove不会重排剩余项——它只删键,不重写整个区块,这点和require不对称,容易误判
复杂点在于:排序是纯静态 JSON 键重排,不改变任何运行时行为,但人眼对顺序敏感。一旦团队协作中有人绕过命令直编 JSON,这个配置就从“规范工具”变成“冲突放大器”。


















