正常行为,composer list仅显示插件注册命令和内置命令,完全忽略composer.json中scripts字段定义的自定义脚本,因其未被注册进命令命名空间,须用composer run-script调用。

composer list 不显示自定义脚本,这是正常行为
composer list 只展示插件注册的命令(如 phpstan:analyse)和 Composer 内置命令(如 install、dump-autoload),它**完全忽略** composer.json 中 scripts 字段定义的自定义脚本。哪怕你写了 "scripts": {"dev:start": "php -S localhost:8000"},composer list 也绝不会输出 dev:start —— 这不是 bug,是设计使然。
自定义脚本不属于 Composer 的“命令命名空间”,它们没有被注册进命令解析器,而是由 composer run-script 单独调度。所以当你在 composer list 输出里搜 dev: 或 test,注定空手而归。
scripts 里的键名会意外占用命令命名空间吗?
不会。脚本名(如 "post-install-cmd"、"dev:clear")只是字符串键,在 Composer 运行时不会被当作命令名注册,也不会与内置命令或插件命令冲突。即使你定义了 "scripts": {"install": "echo 'override'"} ,执行 composer install 仍会走原生逻辑,不会触发你的脚本 —— 因为 install 是保留命令名,Composer 优先绑定自身实现。
但要注意两个例外:
- 如果某个插件恰好注册了一个同名命令(比如某插件提供了
test命令),而你又在scripts里写了"test": "phpunit",那两者互不干扰:composer test调用的是插件命令,composer run-script test才调你的脚本 - 生命周期钩子名(如
pre-autoload-dump)是 Composer 内部事件名,不是命令,也不参与list输出,但它们会被自动触发 —— 和命名空间无关,只和事件机制有关
如何确认某个名字是否已被命令系统占用?
别猜,直接问 --help:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
composer xxx --help成功返回帮助页 → 名字已被命令系统注册(来自内置或插件) -
composer xxx --help报错Command "xxx" is not defined→ 名字空闲,可用于自定义脚本(只要不撞上生命周期钩子名,如post-update-cmd) -
composer list | grep "^xxx$"匹配不到,不代表安全 —— 因为list本身就不列脚本,这个检查只对插件/内置命令有效
特别注意:连字符 - 和下划线 _ 在命令名中含义不同。composer normalize 合法(插件提供),composer normalize:fix 就非法 —— 命令名不支持冒号分隔,那是脚本语法。
scripts 键名写错会导致命名空间污染吗?
不会污染,但会静默失效。比如把 "scripts" 拼成 "script" 或 "Scripts",composer run-script --list 直接无输出,且 composer list 完全感知不到 —— 因为 Composer 根本没读取那段内容。这种错误不占用任何命名空间,只是让脚本“不存在”。
真正容易被忽略的是:脚本键名若含空格或未转义引号(如 "test all"),Composer 会跳过该条目,不报错也不提示,run-script --list 里就看不到它,但 list 依然不受影响 —— 它压根不看 scripts。
脚本和命令系统是两条平行线:一个靠 run-script 驱动,一个靠 Application::find() 查找。混用它们的名字不会打架,但指望 list 来发现脚本,从一开始就是方向错了。

















