composer normalize 是专为 Composer 设计的格式化插件,解决 composer.json 字段顺序、缩进、引号、空行不一致导致的无意义 Git diff 和 CI 失败问题。

composer normalize 是什么,它解决什么问题
composer normalize 是一个独立的 Composer 插件,用来自动格式化 composer.json 文件:统一字段顺序、缩进、引号风格、空行位置,还能补全缺失的 type 或 license 字段。它不改逻辑,只改格式——类似 Prettier 之于 JSON,但专为 Composer 生态设计。
常见错误现象包括:composer install 没报错,但团队 Git 提交里 composer.json 每次都因空格/换行/字段顺序不同产生大量无意义 diff;CI 流水线因格式不一致导致 PR 检查失败;手写时漏掉 autoload 的 psr-4 尾部斜杠,或把 require-dev 写成 require_dev(后者不会报错但被忽略)。
它不是 Composer 内置命令,必须显式安装插件才能用。
怎么装和运行 composer normalize
安装方式取决于是否全局可用或仅项目内使用:
- 推荐项目级安装(避免全局污染):
composer require --dev jean85/composer-normalize
- 装完后直接运行:
composer normalize
—— 默认处理当前目录下的 composer.json
- 加
--dry-run 先看会改什么,不实际写入:composer normalize --dry-run
- 想强制重写所有字段顺序(包括注释位置)?加
--no-interaction 避免交互提示
注意:composer normalize 不会修改 composer.lock,也不影响依赖解析行为。它只读写 composer.json。
为什么不能直接用 json_encode() 或 jq 格式化
因为 composer.json 有语义约定,普通 JSON 工具做不到:
-
name、description、type 必须在最前面,require 在中间,autoload 靠后——composer normalize 知道这个顺序,jq . 不知道
- 它识别
psr-4 命名空间映射里的路径合法性,比如自动补 src/ 后面的 /,而 JSON 格式化工具只会当字符串处理
- 支持保留人工添加的注释(只要写在顶层字段前),
json_encode() 会直接丢光
- 对
scripts 里的命令做基础校验(如检测 phpstan 是否拼错成 phpstam),普通格式化完全不碰逻辑
composer require --dev jean85/composer-normalize
composer normalize—— 默认处理当前目录下的
composer.json
--dry-run 先看会改什么,不实际写入:composer normalize --dry-run
--no-interaction 避免交互提示composer.json 有语义约定,普通 JSON 工具做不到:
-
name、description、type必须在最前面,require在中间,autoload靠后——composer normalize知道这个顺序,jq .不知道 - 它识别
psr-4命名空间映射里的路径合法性,比如自动补src/后面的/,而 JSON 格式化工具只会当字符串处理 - 支持保留人工添加的注释(只要写在顶层字段前),
json_encode()会直接丢光 - 对
scripts里的命令做基础校验(如检测phpstan是否拼错成phpstam),普通格式化完全不碰逻辑
换句话说:它是“懂 Composer”的格式化器,不是“懂 JSON”的格式化器。
容易被忽略的配置和陷阱
composer normalize 支持项目级配置,但很多人没意识到要配:
- 在
composer.json 里加 "extra" 字段就能控制行为:"extra": {
"normalize": {
"indent": 2,
"sort-packages": true,
"strict": true
}
}
-
"strict": true 会让它拒绝格式不合规的输入(比如缺少 license),适合 CI 强制检查;默认是 false,只警告
- 如果项目用了
composer-plugin-api 2.0+,但插件版本太老(如 v2.1.0 以下),composer normalize 会静默失败,终端没输出也没报错——升级到 ^3.0 可解
- 它不处理
composer.lock,但如果你提交了未更新的 lock 文件,Git diff 仍可能混乱;建议搭配 composer update --lock
使用
composer.json 里加 "extra" 字段就能控制行为:"extra": {
"normalize": {
"indent": 2,
"sort-packages": true,
"strict": true
}
}
"strict": true 会让它拒绝格式不合规的输入(比如缺少 license),适合 CI 强制检查;默认是 false,只警告composer-plugin-api 2.0+,但插件版本太老(如 v2.1.0 以下),composer normalize 会静默失败,终端没输出也没报错——升级到 ^3.0 可解composer.lock,但如果你提交了未更新的 lock 文件,Git diff 仍可能混乱;建议搭配 composer update --lock使用
最常被跳过的一步:没把 composer normalize 加进 pre-commit hook 或 CI 脚本里。单靠人记着跑,等于没用。











