根本原因是默认安装保留大量冗余文件且autoload未优化,必须用--no-dev --prefer-dist --remove-vcs重建vendor,并配archive.excludes跳过tests/docs等路径,再启用--classmap-authoritative关闭运行时scandir扫描。

大规模持续部署中,vendor 目录文件数爆表(常见超 200 万 inode)不是磁盘空间问题,而是类加载器反复 scandir() 或构建工具遍历触发的元数据瓶颈;必须从安装源头压制文件生成量,而非事后清理。
为什么 vendor 文件数会突破 NFS/云存储 inode 上限
错误现象不是“磁盘满”,而是 No space left on device(实际 df -i 显示 inode 耗尽)、failed to open stream、CI 构建卡在 composer install 后半段。根源在于:
- 默认
composer install会为每个包保留完整源码树,包括tests/、docs/、.github/、examples/、.git/—— 单个包就能贡献上千文件 -
--no-dev只跳过require-dev包,不删已安装包内部的测试目录 - 未启用
--classmap-authoritative时,PHP 运行时仍会递归扫描整个vendor/目录找类,哪怕文件已被删,扫描动作本身就消耗 inode 查询配额
用 --no-dev --prefer-dist --remove-vcs 重建 vendor 是底线操作
这不是可选项,是每次 CI 构建前必须执行的强制步骤。它从源头控制落地文件数:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
--no-dev:跳过所有开发依赖包(如phpunit、phpstan),直接减少数百个包及其全部子目录 -
--prefer-dist:强制下载 zip 包而非 git clone;dist 包由作者打包,通常已剔除.git、tests/、docs/ -
--remove-vcs:兜底清除 dist 包里残留的.git目录(某些包打包不规范,zip 里仍含.git) - 必须先
rm -rf vendor,再运行composer install;composer update不会重裁剪已有文件
archive.excludes 配置才是压降文件数的关键
仅靠 --prefer-dist 不够——很多包把 tests/ 打进了 zip。必须让 Composer 在解压阶段就跳过这些路径:
- 安装插件:
composer require --dev composer-archive-excludes - 在
composer.json的config块中添加:
"archive": {
"excludes": ["/tests/", "/Tests/", "/docs/", "/examples/", "/.github/", "/CHANGELOG.md"]
}
vendor/ 不会自动清理,需重建才生效别忽略 --classmap-authoritative 对文件系统压力的缓解
即使 vendor/ 已瘦身到 50MB、10 万文件,没关掉 autoload 扫描,集群节点启动时仍会并发 scandir() 整个目录——在 NFS 上每秒触发数万次元数据请求,迅速打爆 inode 队列:
- 确认
composer.json中已设"optimize-autoloader": true - 运行:
composer dump-autoload --optimize --classmap-authoritative --no-dev - 后续
composer install必须带--optimize-autoloader --classmap-authoritative - 验证:
ls -l vendor/composer/autoload_classmap.php应非空;代码中禁用class_exists("SomeDynamicClass")这类动态拼名逻辑
真正决定能否扛住千节点并发启动的,从来不是压缩率或下载速度,而是 autoload_classmap.php 是否真实生效、以及 vendor/ 目录是否彻底脱离运行时扫描路径。










