composer如何设置脚本钩子(scripts)?(pre-install-cmd等示例)

1次阅读

scripts 钩子需在 composer.json 顶层 scripts 对象中,使用预定义小写事件名(如 pre-install-cmd);值可为字符串、数组或对象;php 类方法调用须显式引入 vendor/autoload.php;命令失败会中断执行,建议用 php 脚本保障跨环境一致性。

composer如何设置脚本钩子(scripts)?(pre-install-cmd等示例)

composer.json 里 scripts 怎么写才生效

脚本钩子必须写在 composer.jsonscripts 字段下,且顶层键名是预定义的事件名(比如 pre-install-cmd),不是随便起的。Composer 不会执行拼错、大小写不符或未注册的钩子名。

  • 确保 composer.json 根层级有 "scripts": { ... } 对象,不是嵌套在其他字段里
  • 事件名严格区分大小写:pre-install-cmd 有效,pre-install-CMDpreinstall-cmd 无效
  • 值可以是字符串(单条命令)、字符串数组(顺序执行)或对象(带 scriptEvent 字段的完整配置)
  • 修改后无需额外注册,运行 composer install 等对应命令时自动触发

pre-install-cmd 和 post-update-cmd 的典型用途差异

pre-install-cmdcomposer install 解析依赖前执行,适合做环境检查、清理缓存或校验配置;post-update-cmdcomposer update 完成依赖安装后触发,更适合生成 autoload、构建前端资源或刷新路由缓存。

  • pre-install-cmd:常用于 php -v 检查 PHP 版本、test -f .env 确认环境文件存在
  • post-update-cmd:常见于 php artisan optimize:clearlaravel)、composer dump-autoload 或调用 webpack 构建
  • 注意:post-install-cmd 只在首次 install 触发,不是每次 update;想覆盖两者行为,得同时写 post-install-cmdpost-update-cmd

脚本里调用 PHP 类方法要加 vendor/autoload.php

直接写 "MyScript::run" 这类静态方法调用时,Composer 默认不会自动加载你的类——它只负责执行命令,不接管 PHP 自动加载上下文。

  • 必须显式引入 autoloader:"php -r "require 'vendor/autoload.php'; MyScript::run();""
  • 更稳妥的做法是封装成独立可执行脚本(如 bin/deploy.php),然后在 scripts 中写 "php bin/deploy.php"
  • 别依赖当前工作目录是项目根目录——用 __DIR__getcwd() 显式处理路径,否则 CI 环境容易失败
  • 错误现象示例:PHP Fatal Error: class 'MyScript' not found,就是没加载 autoload 导致的

调试 scripts 钩子为什么没运行

最常见原因是命令退出码非 0:只要脚本中任意一条命令返回非零状态,Composer 就中断后续流程,并可能静默跳过后续钩子(尤其 pre-* 类型)。

  • -v 参数看详细日志:composer install -v,能明确看到 “Executing script …” 和返回码
  • Shell 命令记得加 set -e 或检查 $?,避免部分失败被忽略(比如 cp 找不到源文件却继续往下)
  • windows 用户注意:CMD 不支持单引号包裹多命令,得改用双引号 + ^ 换行,或直接用 PowerShell 脚本
  • CI 环境中 composer install --no-interaction 仍会触发 scripts,但交互式提示(如 readline)会卡住,务必改成非交互模式

脚本钩子本身不复杂,真正麻烦的是跨环境一致性——本地跑通的 shell 命令,在 dockergithub Actions 里常因 PATH、权限或扩展缺失而失败。建议所有非 trivial 的逻辑都抽到 PHP 脚本里,用 Composer 自带的 autoloader 加载,而不是砌 shell 行为。

text=ZqhQzanResources