开启 “sort-packages”: true 即可使 require 等字段按 ASCII 字母序自动排序,仅在 composer require 或 composer update –lock 等写入操作时生效,不影响依赖解析、安装行为及 composer.lock 结构。

composer.json 里 require 包不按字母排序?开 sort-packages 就行
Composer 默认不会自动整理 require 和 require-dev 里的包名顺序,每次 composer require 或 composer update 都可能把新包插在末尾或中间,导致 diff 难读、协作混乱。解决方法很简单:在 composer.json 根对象里加一行 "sort-packages": true。
这个配置只影响后续的写入操作(比如 composer require、composer update),不会自动重排已有内容——得手动跑一次 composer install 或 composer update --lock 才会触发重排序。
-
sort-packages是布尔值,只能是true或false,不能写字符串"true" - 它只对
require、require-dev、conflict、replace、provide这几个字段生效,不影响autoload或自定义配置项 - 排序规则是纯 ASCII 字母序,
symfony/console会排在zendframework/zend-diactoros前面,不区分 vendor 名和 package 名层级
为什么开了 sort-packages 后 composer.json 还没变?
因为 Composer 不会在读取配置时主动重写文件,它只在「有包变动且需要写入 composer.json」时才应用排序逻辑。常见误以为“开了就立刻生效”的原因:
- 只改了
composer.json但没执行任何命令——配置不会自己干活 - 只运行了
composer install(没改动依赖)——没有写入composer.json的必要,也就跳过排序 - 用
composer require --no-update加包——它会直接写进composer.json,但跳过更新流程,此时sort-packages也不触发
真正可靠的触发方式是:composer require some/package(不带 --no-update),或 composer update --lock(哪怕没升级包,也会重写 lock 并顺手整理 composer.json)。
sort-packages 对 lock 文件和安装行为有影响吗?
没有。它只改变 composer.json 中依赖字段的键顺序,不改变任何解析逻辑、安装顺序、版本解析结果或 composer.lock 的内容结构。lock 文件里的 packages 数组仍按实际安装顺序排列,和 composer.json 的排序无关。
也就是说,开启后你看到的只是「人类可读性提升」,不是「依赖解析逻辑变更」。CI/CD 流程、生产环境部署、甚至 composer install 的行为都完全不受影响。
- 如果团队多人共用同一份
composer.json,建议统一开启,避免每次git diff都出现无意义的顺序抖动 - 某些 IDE 或编辑器(如 PHPStorm)会基于
sort-packages状态调整自动补全提示顺序,但这是客户端行为,和 Composer 本身无关 - 如果你用脚本批量修改
composer.json(比如 sed / jq),要注意:手动写入时不会受该配置约束,只有 Composer 自己写入才排序
想全局默认开启?别费劲了,老老实实每个项目配
Composer 没有全局配置项能控制 sort-packages,~/.composer/config.json 里设 "sort-packages": true 是无效的。它必须出现在每个项目的 composer.json 根层级。
最省事的做法是:把带 "sort-packages": true 的最小化 composer.json 当作模板,新建项目时直接复制;或者用 composer init 初始化时回答“yes”给“Sort packages alphabetically?”提示(新版 Composer CLI 会主动问这个)。
容易被忽略的一点:如果项目用了 composer create-project 拉某个 skeleton,而那个 skeleton 的 composer.json 没开 sort-packages,那生成的项目也不会有——得自己补上,别指望继承。