Composer 不支持安装时跳过文件,archive.exclude 仅影响自身包发布,对 vendor 中第三方包无效;精简 vendor 应用 --no-dev、--prefer-dist 及 post-install-cmd 脚本清理。

Composer 本身不支持“安装时跳过某些文件”的运行时机制,所谓“定制化安装排除文件”,本质是控制「包发布时的内容」或「安装后清理」,不是在 composer install 过程中动态过滤。
archive.exclude 只影响你自己的包打包,对 vendor 里的第三方包无效
你在项目根目录的 composer.json 里加 "archive": {"exclude": ["/tests/"]},不会让 composer install 下载的 monolog/monolog 少掉 tests 目录。它只在你执行 composer archive 或向 Packagist 发布新版本时起作用——而且仅限于你自己的包。
- 第三方包是否含
.git、docs/、examples/,取决于它们作者配没配archive.exclude或.gitattributes - 你改自己项目的这个字段,对
vendor/里任何其他包都无感 - 常见错误:看到
vendor/symfony/console/tests/还在,就去改自己项目的archive.exclude——这完全不相关
想减小 vendor 体积?用 --no-dev 和 --prefer-dist
真正能缩小 vendor/ 占用的,是部署时的参数组合,不是排除配置:
-
composer install --no-dev:跳过require-dev下的所有包(如phpunit/phpunit),但不影响已安装包里的tests/目录 -
composer install --prefer-dist:强制走 zip 包而非 git clone,避免带入.git目录(前提是包作者发布了 dist) -
composer install --optimize-autoloader --no-dev --prefer-dist:三者合用是上线标准命令
要删 vendor 里某个包的 tests/docs?只能靠 post-install-cmd 脚本
如果某依赖(比如 guzzlehttp/guzzle)总带着大体积的 docs/ 和 src/Tests/,而你确认这些文件运行时完全不需要,唯一可控的办法是安装后手动清理:
- Linux/macOS 示例(写进
composer.json的scripts):"post-install-cmd": ["find vendor/guzzlehttp/guzzle -type d \( -name 'tests' -o -name 'docs' -o -name 'examples' \) -exec rm -rf {} + || true"] - Windows 用户必须换用 PowerShell 或 PHP 脚本,
rm -rf不可用 - 多个包要清理?别堆一堆
find命令,合并成一个 PHP 脚本调用更可靠,也避免权限失败时 Composer 不报错
autoload.exclude-from-classmap 不是排除文件,是优化 classmap 扫描
这个字段常被误读为“禁止加载某文件”,其实它只在 composer dump-autoload --optimize 生成 autoload_classmap.php 时跳过指定路径,且仅对 classmap 类型生效:
- 对
psr-4、autoload.files完全无效 - 路径匹配的是文件系统路径,不是命名空间;写
"tests/*"会跳过整个tests/目录下的所有类文件(即使它们有合法class声明) - 它不删除文件,也不阻止
autoload.files里明确require的文件执行
最常被忽略的一点:你看到的 vendor/ 里那些“多余文件”,99% 是包作者没配 .gitattributes 或 archive.exclude;你本地改配置,既不能改变已发布的 dist 包内容,也不能干预 git clone 行为。真要精简,得从源头推动维护者加 export-ignore,或者接受脚本清理这个折中方案。


















