composer normalize 非原生命令,需安装 ergebnis/composer-normalize 插件并配置 "extra": {"normalize": true} 才生效;它只标准化顶层字段顺序与格式,不处理 require/require-dev 键序,且与 composer format 逻辑冲突、不可混用。

composer normalize 不是 Composer 原生命令,它依赖 ergebnis/composer-normalize 插件,且只标准化字段顺序、缩进和空行,不重排 require/require-dev 键名 —— 它和 composer format 是两套逻辑,混用会互相覆盖。
为什么 composer normalize 看起来没生效
常见错误现象:composer require foo/bar 后 composer.json 顺序依旧混乱,或执行 composer normalize 报错 “command not found”。
- 插件未安装:必须先运行
composer require --dev ergebnis/composer-normalize,否则命令不存在 - 配置缺失:插件默认不启用自动标准化,需在
composer.json的extra字段中显式开启,例如:"extra": { "normalize": true } - 它不监听
composer install:只在composer update或composer require写入composer.json时触发,且仅作用于name、description、type、license、autoload等顶层字段的顺序与格式,对require和require-dev的键序完全不管 - 和
sort-packages冲突:若同时启用了"config": {"sort-packages": true},composer require会先按字母重排依赖,再由 normalize 重排顶层字段——但 normalize 不保证最终顺序可预测,Git diff 易爆炸
composer normalize 和 composer format 的核心区别
二者目标相似,但实现机制和影响范围完全不同:
-
composer format(Composer 2.5.0+ 原生):只美化格式(缩进、空行、引号、逗号),保留所有字段原始顺序(包括require中包的声明顺序),不改变语义,支持--dry-run -
composer normalize(插件):按预设 schema 强制重排字段位置(如把name推到最前、scripts放最后),并标准化空行与缩进;但它会忽略注释、不处理require键序,且无法关闭字段重排行为 - 不能共存于同一工作流:比如在 CI 中先跑
composer normalize再跑composer format,后者可能把 normalize 刚排好的字段顺序又“还原”回原始位置(因 format 只做格式化,不干预顺序) - 插件配置更细:可通过
extra.normalize控制是否排序顶层字段、是否保留注释、是否强制双引号等,但这些选项在原生format中不存在
如何安全接入团队协作流程
关键不是“装上就行”,而是避免格式工具成为 Git 提交噪声源:
- 选一个主力方案:团队统一用
composer format(推荐),或统一用ergebnis/composer-normalize,不要混用 - 禁止手动编辑后直接提交:哪怕只是改个版本号,也必须走
composer format或composer normalize过一遍,否则composer.json格式会随人而异 - CI 中加校验:在 GitHub Actions 或 GitLab CI 里加入
composer format --dry-run && echo "✅ composer.json is formatted"
,失败即中断构建 - 别信 IDE 自动保存:VS Code 的 JSON 格式化插件会加尾逗号、换引号风格、重排 key,而 Composer 写入时会抹掉这些——来回覆盖导致每次
git diff都显示整块变更
真正容易被忽略的是:插件标准化后的字段顺序,可能和某些老旧部署脚本硬编码的读取逻辑冲突(比如假设 autoload 总在第 5 行)。如果你的运维链路里有解析 composer.json 的 Shell 脚本或 Python 工具,先验证它们是否依赖原始顺序——否则 normalize 一跑,上线就挂。


















