sort-packages仅在composer require或update重写composer.json时触发重排,install不生效;按vendor/name ASCII序排序,只作用于require和require-dev区块内键序,不影响安装逻辑与运行行为。

它只在写入 composer.json 时重排 require 和 require-dev 的键顺序,其他时候完全不生效,也不影响安装行为或运行逻辑。
sort-packages 什么时候会真正重排依赖
这个配置不是监听文件变化的“实时整理器”,它只在 Composer 主动修改 composer.json 的瞬间触发:
-
composer require vendor/package—— 新包会按字母序插入到对应区块(require或require-dev)中,不是简单追加到末尾 -
composer update vendor/package或全量composer update—— 仅当该操作导致composer.json被重写(例如版本号变更、约束更新)时才重排;如果所有依赖已锁定且无变更,Composer 可能跳过写入,也就不会重排 -
composer install永远不触发 —— 它只读composer.lock,不碰composer.json,哪怕你改了配置也毫无反应
为什么加了 "sort-packages": true 却没看到变化
常见现象是配置写了、保存了、也跑了命令,但 composer.json 里的依赖顺序还是乱的。原因通常有这几个:
- 误用了
composer install:它根本不修改composer.json,所以排序逻辑压根不会跑 - 已有依赖未被“触碰”:
sort-packages是增量式重排,只影响本次新增或更新的条目;已存在的、未改动的包不会被挪动位置 - 配置写错位置或类型:
"sort-packages": true必须放在composer.json根级的"config"对象里,不能是字符串"true",也不能漏掉"config"外层包裹 - 手动编辑过
composer.json:比如直接删了某行再粘贴新包,这种绕过 Composer 命令的操作不会触发排序
排序规则和容易被忽略的细节
它用的是纯 ASCII 字符串排序,不是“自然排序”,也不是大小写不敏感:
- 包名格式是
vendor/name,排序依据就是这个完整字符串,比如monolog/monolog排在psr/log前面(mp) - 大写字母排在小写字母前面:
Symfony/flex(S=83)会排在symfony/console(s=115)之前 - 下划线
_(ASCII 95)排在所有字母前:_my/package会出现在abc/def上方 - 注释和空行不随包移动:原有注释会留在原位置,可能错位到别的包旁边,看起来很混乱
- 区块隔离:
require和require-dev各自独立排序,不会跨块合并或交换
想全量重排已有依赖怎么办
单次 composer require 或 update 只动新增/更新项。要让整个 require 区块从头排一遍,得用点“暴力”办法:
- 临时清空
composer.json中的"require"和"require-dev"内容(保留结构),然后逐个composer require vendor/package回来 —— 新包会严格按字母序插入 - 注意:生产项目慎用,尤其涉及大量私有包或特殊约束时,容易漏掉版本约束或引发冲突
- 更稳妥的做法是配合
composer normalize(需插件),它能处理注释、空行、字段顺序等完整规范化,而sort-packages只管依赖键序
真正麻烦的从来不是配置本身,而是混合使用:有人手动改 composer.json 加包,又有人用 require 命令,结果 Git 提交里一半是功能变更,一半是键序抖动。要么全交给 Composer 管,要么关掉它,别半吊子用。


















