Composer 官方配置中不存在 scripts-dev 字段,所有脚本必须定义在 scripts 下;可通过 dev: 前缀命名并手动触发,或在脚本中检查 APP_ENV 环境变量实现开发环境限定。

Composer 里没有 scripts-dev 配置项
直接说结论:Composer 官方配置格式中不存在 scripts-dev 这个字段,它不是合法的 composer.json 键名。试图写入会导致 composer validate 报错,或被静默忽略。
开发环境脚本只能放在 scripts 里,靠命名或条件区分
所有自定义脚本必须定义在 scripts 对象下,但你可以通过命名约定 + 手动触发方式实现“仅开发环境运行”的效果:
- 用前缀区分,比如
dev:clear-cache、dev:setup-db,避免和生产脚本(如post-install-cmd)混淆 - 脚本本身不自动执行,只在你明确运行
composer run dev:setup-db时才触发 - 若需自动判断环境,得在脚本命令里加逻辑,例如用
php -r "echo getenv('APP_ENV') ?: 'prod';"检查环境变量 -
scripts中的事件钩子(如post-autoload-dump)默认全局生效;若只想开发环境触发,需在对应命令中加守卫逻辑,例如:#!/usr/bin/env php
别误信“scripts-dev”是 Composer 内置功能
网上有些文章把第三方插件(如 hirak/prestissimo 或自研脚本包装器)的行为当成 Composer 原生能力,或者把 Laravel 的 artisan 环境判断逻辑套到 composer.json 上。实际查官方文档或运行 composer schema 都能确认:scripts-dev 不在 schema 定义中。
常见错误现象包括:
-
composer install后提示Invalid argument supplied for foreach()—— 很可能是自定义脚本读取了不存在的scripts-dev字段并做了空遍历 -
composer validate输出[ERROR] The property scripts-dev is not defined and the definition does not allow additional properties. - CI 流水线里脚本没执行,因为 CI 默认不设
APP_ENV=dev,而你的脚本又没 fallback 逻辑
真正可靠的替代方案:用 require-dev + 脚本封装
如果某些脚本依赖开发专用工具(如 phpunit、phpstan),应确保它们只出现在 require-dev,并在 scripts 中调用时做存在性检查:
{
"require-dev": {
"phpunit/phpunit": "^10.0"
},
"scripts": {
"test": "command -v phpunit >/dev/null 2>&1 && phpunit || echo 'phpunit not available in this environment'"
}
}
这样既避免生产环境误装 dev 依赖,又让脚本行为更健壮。关键点在于:脚本是否执行,取决于你如何调用它、环境变量是否存在、命令是否可用——而不是靠一个虚构的配置节来“开关”。
最常被忽略的是:脚本路径未加 vendor/bin/ 前缀导致本地可跑、CI 报 command not found;还有就是忘记给自定义 PHP 脚本加 #!/usr/bin/env php 头,导致 sh 尝试解析而非交给 PHP 执行。










