composer 2.5.0+ 原生支持 composer format,可安全美化 composer.json:重排缩进、空行、引号与逗号,不改变语义和字段顺序;支持 --dry-run 预览、指定路径及 ci 自动校验,避免 jq 或 json.tool 破坏注释、顺序与可维护性。

composer.json 用 composer format 自动美化
Composer 从 2.5.0 版本起原生支持格式化,不用装插件、不依赖第三方工具。执行后会按官方规范重排缩进、调整空行、统一引号和逗号位置,且**不改变语义或顺序**(比如 require 和 autoload 的先后关系保留)。
常见错误现象:手动改完 composer.json 后运行 composer install 报 JSON decode error: Syntax error,其实只是换行/逗号漏了,不是语法错——composer format 能直接暴露这类低级问题。
- 确保 Composer 版本 ≥ 2.5.0:
composer --version,低于就先composer self-update - 直接运行:
composer format(默认处理当前目录下的composer.json) - 想格式化指定文件:
composer format /path/to/composer.json - 加
--dry-run参数预览改动,不写入磁盘:composer format --dry-run
为什么不用 jq 或 python -m json.tool
这些通用 JSON 工具会「标准化」输出:强制双引号、删注释、重排序 key(比如把 name 排到最前),但 composer.json 不是纯 JSON——它允许注释(虽然解析时忽略)、依赖声明顺序影响安装行为(如 require-dev 里的包不该被生产环境加载),而且 Composer 内部读取时依赖字段原始位置(比如某些插件靠 scripts 的 key 顺序做 hook)。
用 jq . composer.json > tmp && mv tmp composer.json 看似省事,实际可能:
- 把 "php": "^8.1" 改成 "php": "^8.1"(看着一样,但换行/空格变了,git diff 爆炸)
- 把多行 scripts 压成一行,可读性归零
- 某些字段(如 config 下的 process-timeout)被重排后,人眼难定位
- 别用
jq处理composer.json,除非你明确只要语法合法、完全不管可维护性 -
python -m json.tool同理,且不兼容 Windows 默认编码(可能乱码) - 真正需要脚本化批量处理时,优先选
composer format+--working-dir
CI/CD 里自动检查格式是否合规
团队协作中,有人手抖提交了没格式化的 composer.json,光靠 PR 描述提醒效果差。直接在 CI 里跑校验,失败即拒收,比事后 review 靠谱。
GitHub Actions 示例(放在 .github/workflows/composer-check.yml):
run: |
composer format --dry-run
if [ $? -ne 0 ]; then
echo "composer.json is not formatted. Run 'composer format' locally."
exit 1
fi- 关键在
--dry-run:只检测,不修改,避免 CI 里意外覆盖文件 - 注意:Git 默认不跟踪空格/换行差异,所以得确保仓库启用
core.whitespace = trailing-space,space-before-tab,否则格式问题可能被忽略 - 如果项目还用了
composer.lock,记得composer update --lock后再跑 format,否则 lock 文件和 json 不匹配
手动编辑时最容易被忽略的三个点
即使开了自动格式化,人肉改配置时仍会踩坑。这三个点不报错,但会让后续协作或升级变麻烦:
-
version字段别硬写死,比如"version": "1.0.0"—— 应该删掉,让 Composer 根据 git tag 自动推导,否则发版时容易忘同步 -
autoload里用psr-4时,命名空间末尾必须带反斜杠:"App\": "src/",写成"App": "src/"会导致类找不到,且composer format不会修正这种逻辑错误 - 添加新依赖后,别只改
require,顺手跑composer update vendor/package-name --no-install更新 lock 文件中的精确版本,不然下次composer install可能拉旧版
格式只是表象,真正卡人的永远是字段语义和上下游联动。一个空格对 CI 来说不算事,但少个反斜杠能让整个 autoload 失效,还没提示。










