Composer真正识别的脚本事件是pre-install-cmd、post-install-cmd、pre-update-cmd、post-update-cmd;它们必须带-cmd后缀,否则被完全忽略且无报错。

Composer 的 pre-install 和 post-update 不是官方支持的脚本事件 —— 它们根本不存在。 你看到的配置大概率是拼写错误、文档过时,或者混淆了 pre-install-cmd / post-update-cmd 这类真实可用的钩子。
哪些脚本事件才是 Composer 真正识别的?
Composer 只认 xxx-cmd 后缀的脚本键名。核心命令钩子包括:
-
pre-install-cmd:在composer install开始前触发(仅当锁文件存在且未修改时才执行) -
post-install-cmd:install成功完成后触发(无论是否从锁文件安装) -
pre-update-cmd:在composer update解析依赖前触发 -
post-update-cmd:update成功写入composer.lock后触发
注意:pre-install 和 post-update(无 -cmd)会被 Composer 完全忽略,不会报错,也不会执行 —— 这是最容易踩的静默陷阱。
如何正确配置 post-update-cmd 执行自定义脚本?
在 composer.json 的 scripts 段落中声明:
{
"scripts": {
"post-update-cmd": [
"@php artisan clear-compiled",
"npm run build"
]
}
}
说明:
- 数组内每个字符串都会按顺序执行;以
@开头表示调用其他脚本(如@php是内置别名) - 命令必须可被 shell 直接运行;若含空格或特殊字符,需确保宿主环境支持(例如 Windows 下
npm要在 PATH 中) - 脚本失败(非零退出码)会导致整个
composer update中断 —— 若想忽略失败,可加|| true(不推荐用于关键步骤)
为什么 pre-install-cmd 很少被触发?
pre-install-cmd 的触发条件非常苛刻:
- 必须运行的是
composer install(不是update) - 项目必须已有
composer.lock -
composer.json自上次install后未被修改(否则会退化为update流程)
换句话说:它只在「纯部署场景」下稳定生效(比如 CI/CD 拉取代码后直接 install)。本地开发中几乎总走 update 路径,所以更建议统一用 post-install-cmd + post-update-cmd 覆盖两类场景。
常见错误与绕过方案
现象:composer install 运行后,预期的钩子脚本没执行。
- 检查
composer.json中键名是否写成post-update(缺-cmd)→ 改为post-update-cmd - 确认脚本内容是否含语法错误(如
npm run build在当前目录无package.json)→ 先手动执行验证 - 某些共享主机禁用
exec()→ 钩子会静默失败;可在脚本开头加echo "hook running"排查 - 想让钩子只在特定环境下运行(如仅 CI)→ 用环境变量判断:
"post-update-cmd": "if [ \"$CI\" = \"true\" ]; then npm ci && npm run build; fi"
真正要小心的不是怎么写钩子,而是 Composer 对脚本名称的严格校验 —— 少一个 -cmd,就等于没写。










