Composer 的 scripts 不是钩子系统,仅是按名触发的命令列表,必须定义在根 composer.json 中,且名称须严格匹配内置事件名(如 post-install-cmd)或通过 composer run 手动执行自定义名(如 test)及带前缀别名(如 ci:test)。

Composer 的 scripts 不是“钩子系统”,它只是按名称触发的命令列表,没有生命周期语义(比如 pre-install、post-autoload-dump 并非真正钩住事件,而是靠 Composer 自己约定调用时机)——配置错名字或依赖顺序,脚本就根本不会执行。
scripts 字段必须写在根 composer.json 里
子包或 vendor/ 下的包里的 scripts 不会被自动识别。只有项目根目录的 composer.json 中的 scripts 才有效。
- 运行
composer run test时,只读取当前目录下的composer.json - 如果在子目录执行,会报错
Could not find composer.json,不是“找不到脚本” - 多项目共用一套脚本?得用 symlink 或构建工具统一生成根
composer.json
支持的 script 名称分三类:内置事件名、自定义名、带前缀的别名
Composer 会自动在某些命令前后触发同名 script(如 post-install-cmd),但前提是名字完全匹配——拼错一个字母、多一个空格、大小写不一致,都不会触发。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 内置事件名(自动触发):
pre-install-cmd、post-autoload-dump、post-root-package-install等,完整列表见 Composer 官方文档 scripts#event-names - 自定义名(需手动运行):
"test": "phpunit"→ 运行composer run test - 带前缀别名(推荐用于组织):
"ci:test": "phpunit --coverage-text"→ 运行composer run ci:test,但注意:这种写法在旧版 Composer(Script 'ci:test' is not defined
script 命令里引用其他 script 要用 @xxx 语法,不能直接写名字
想在一个 script 里串起多个步骤,比如先清理再测试,不能写 "test": "rm -rf build && phpunit" —— 这样耦合高、难复用、Windows 下还可能失败。应该拆成独立 script 并用 @ 引用。
- 正确写法:
"clean": "rm -rf build", "test": "@clean && phpunit" -
@clean会被 Composer 替换为实际命令,且自动处理跨平台路径分隔符(Windows 下也能跑) - 错误写法:
"test": "clean && phpunit"→ 报错clean: command not found,因为 shell 不认识clean这个命令 - 嵌套层级别太深:超过两层
@调用容易导致变量展开异常或超时,建议单个 script 控制在 3 步以内
环境变量和参数传递有明确限制
Composer scripts 默认不继承 shell 的全部环境变量,也不支持直接传参给子命令(比如 composer run test -- --filter=MyTest 是无效的)。
- 要传参,必须用
--分隔:composer run test -- --filter=MyTest,此时--filter=MyTest会透传给test脚本定义的命令 - 想在 script 中读取项目信息,可用 Composer 内置变量:
$COMPOSER_HOME、$COMPOSER_BIN_DIR,但$PWD可能是 vendor 目录而非项目根目录,建议用$(pwd)显式获取 - 敏感信息(如 API key)不要硬编码在
scripts里,应通过.env或composer config注入,否则会进 git 历史
最常被忽略的是:Composer 不保证 script 执行顺序的原子性。比如两个 post-autoload-dump,一个来自 root,一个来自 vendor 包,谁先谁后不确定;如果逻辑强依赖顺序,就得合并到同一个 script 里手动控制。

















