composer install --no-dev 无法删除 vendor 中的 tests/ 目录,因为它仅跳过 require-dev 声明的包(如 phpunit/phpunit),但不干预正式依赖包(如 symfony/console)内部自带的 tests/ 等非运行文件——这些是包作者源码的一部分,Composer 默认原样解压;真正排除需依赖 archive.excludes 配置或 composer-archive-excludes 插件在 dist 解压阶段过滤。

composer install --no-dev 为什么删不掉 vendor 里的 tests/ 目录
因为 --no-dev 只跳过 require-dev 区块声明的包(比如 phpunit/phpunit),但对已安装的正式依赖(如 monolog/monolog)内部是否含 tests/、docs/ 完全不管——这些目录是包作者源码的一部分,Composer 默认原样解压。
常见错误现象:vendor/ 占用 150MB+,其中 symfony/console 下的 Tests/ 目录就占 20MB,但运行时根本不会加载它。
-
--no-dev是必须加的,但它只是第一步,不是“瘦身”本身 - 真正起作用的是安装方式:如果走
dist(zip 包),才可能利用.gitattributes规则过滤;走source(git clone)则完全绕过裁剪 - 确认当前安装方式:运行
composer install -v,看日志里出现的是Downloading ... .zip还是Cloning ...
用 archive.excludes 配置在解压阶段跳过 tests/docs
这是最干净、可复现的方式——在 zip 包解压前就排除路径,不落地、不残留。它只对 dist 安装生效(即默认行为),且需写进项目级配置,不是全局设置。
执行以下命令启用:
composer config archive.excludes '["tests/*", "Tests/*", "test/*", "docs/*", "examples/*", ".github/*", ".git"]'
注意:archive.excludes 是数组格式字符串,引号和括号缺一不可;路径通配符只支持 *,不支持 ** 或正则。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 该配置会写入当前项目的
composer.json的config块,不影响其他项目 - 下次
composer install时,所有从 dist 下载的包都会按此规则解压(前提是包发布者用了 zip 格式) - 不生效?检查包是否真走 dist:有些包(尤其 dev 版本或 fork)强制走 source,此时
archive.excludes完全无效
用 composer-archive-excludes 插件替代手动 rm
比起 post-install-cmd 里写 find vendor -name tests -exec rm -rf {} +,插件更可靠:它在 Composer 解压 ZIP 的瞬间就过滤路径,避免“先写再删”的冗余 IO 和权限问题。
安装插件:
composer require --dev composer-archive-excludes/composer-archive-excludes
插件自动读取 archive.excludes 配置(如果已设),无需额外配置。它兼容 Composer 2.5+,且不干扰 autoload 逻辑。
- 不要和
post-install-cmd清理脚本共存,否则可能重复删、报错中断 - Windows 用户注意:插件依赖 PHP 的
zip扩展,确保php -m | grep zip有输出 - 验证是否生效:安装后进某个包目录(如
vendor/monolog/monolog),直接ls看是否存在tests/—— 没有就是成功
--optimize-autoloader 和 --classmap-authoritative 不删文件,但能缩小实际体积
--optimize-autoloader(或 -o)生成 vendor/autoload_classmap.php,只包含被 autoload 声明实际引用的类;--classmap-authoritative 则强制只从此 classmap 加载,彻底跳过文件系统扫描。它们不删除 tests/ 目录,但会让这些目录“不可见”——Docker 构建时 COPY vendor 后,运行时根本不会访问它们,相当于白占空间。
生产环境推荐组合使用:
composer install --no-dev --optimize-autoloader --classmap-authoritative --prefer-dist
-
--prefer-dist强制走 zip 包,确保archive.excludes或插件能起作用 -
--classmap-authoritative对只读文件系统(如容器 rootfs)很关键,避免因opendir()失败导致 fatal error - 别指望
--optimize-autoloader减小磁盘占用——它只加速加载,du -sh vendor数值几乎不变
tests/ 的手段;事后用脚本删,总会有漏网之鱼,比如某些包把测试放在 src/Tests 里,而 autoload 又没声明它——这种路径既不被加载,也不被插件识别,只能靠人工判断。

















