--no-scripts是唯一可靠手段,因post-install-cmd等scripts字段定义的钩子在composer install成功后必然执行,无沙箱校验;它原生跳过全部脚本解析与执行,不影响依赖下载、autoloader生成,但需配合--no-plugins才能彻底禁用插件注入的钩子。

必须加 --no-scripts,否则 post-install-cmd 等钩子必然执行,不是“可能”,是“一定”。
为什么 --no-scripts 是唯一可靠手段
Composer 的 scripts 字段定义的钩子(如 post-install-cmd、pre-autoload-dump)在 composer install 成功后无条件触发。它不检查脚本内容是否安全,也不做任何沙箱隔离——exec("rm -rf /") 和 php artisan key:generate 对它来说没区别。
-
--no-scripts是 Composer 原生支持的开关,直接跳过整个scripts执行流程,不解析、不 eval、不 fork - 只靠修改
composer.json临时清空"post-install-cmd": []不可靠:CI 构建用的是 Git 检出的原始文件,没人帮你改 - 别指望
--dry-run:它照样会触发pre-install-cmd,且不保证所有钩子都跳过
--no-scripts 会影响哪些事,又不影响哪些
加了 --no-scripts 后,依赖照下、vendor/autoload.php 照生成、composer.lock 照写,但所有脚本都不跑。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 会被跳过的典型动作:
php artisan optimize、npm run build、php -r "copy('.env.example', '.env')" - 不会被跳过的动作:
vendor/目录创建、类自动加载映射生成、插件注册(注意:插件逻辑仍会运行) - 特别注意:
--no-scripts不等于--no-autoloader;后者会破坏基础运行能力,导致Class not found
仅禁用部分脚本?没有原生方案,别白费劲
Composer 不提供 --skip-script=post-install-cmd 这类细粒度控制。所谓“跳过某个包的脚本”,本质是误解——脚本是项目级配置,不是按包绑定的。
- 如果你只想屏蔽 Laravel 的
post-root-package-install,但保留自己写的post-install-cmd,做不到 - 可行替代方案只有两个:
– 在 CI 脚本里用sed或jq临时注释掉特定键(风险高,易出错)
– 把问题脚本替换成空数组:"post-install-cmd": [](不是null,否则会被忽略) - 千万别用
COMPOSER_NO_INTERACTION=1或--no-interaction:它们对脚本执行毫无影响
更彻底的禁用:必须搭配 --no-plugins
--no-scripts 只管 composer.json 里的 scripts 字段,但插件(plugin)能绕过它,在加载时悄悄注册新钩子。
- 比如
symfony/flex会在post-install-cmd外额外触发自己的初始化逻辑 - 要真正切断所有钩子执行链,必须同时用:
composer install --no-scripts --no-plugins -
--no-plugins会跳过插件发现、加载、激活全过程,包括vendor/下所有插件的activate()方法 - 副作用:某些依赖安装行为(如
composer/installers的路径重定向)会失效,需提前确认是否依赖这类插件
真正容易被忽略的点在于:脚本失败时钩子根本不会触发,所以你以为加了 --no-scripts 就万无一失,其实构建失败时连日志上报都得靠 shell wrapper 手动捕获——那又是另一层事情了。

















