exclude-from-classmap仅影响classmap自动加载,需配合"classmap"配置使用,不作用于PSR-4/PSR-0或vendor目录;archive.excludes仅控制打包排除,不影响安装与autoload;手动删除vendor子目录无效且危险。

composer install 时跳过某些目录:用 exclude-from-classmap
Composer 默认会扫描整个 vendor 和项目源码,把所有 PHP 文件按命名空间映射进自动加载。但有些目录(比如测试用的 tests/、文档 docs/、或临时生成的 build/)不该被 autoload 扫到,否则可能引发类名冲突或性能拖慢。
真正起作用的是 autoload.exclude-from-classmap 配置项,它只影响 classmap 类型的自动加载,不影响 PSR-4/PSR-0 —— 这点很多人混淆。
-
exclude-from-classmap是数组,每个元素是相对项目根目录的路径字符串,支持通配符*(但不支持**) - 它只在你用了
"classmap": ["src/"]这类显式配置时才生效;纯 PSR-4 项目里设了也基本没用 - 路径末尾加不加
/都行,但推荐加,避免误排除同名文件(比如test目录 vstest.php)
"autoload": {
"classmap": ["src/", "legacy/"],
"exclude-from-classmap": ["tests/", "docs/", "build/*"]
}
想彻底不让 composer 处理某个目录:改 composer.json 的 archive.excludes
这个配置和自动加载无关,只影响 composer archive 或打包发布时的文件剔除。但它常被误当成“忽略目录”的通用方案——其实对 install、update 完全没作用。
如果你只是不想让某些目录出现在 zip 包里(比如 CI 日志、本地配置模板),才用它:
- 值为字符串数组,支持 glob 模式(
**可用) - 路径是相对于项目根目录的,不是 vendor
- 不影响依赖安装、autoload、脚本执行等任何运行时行为
"archive": {
"excludes": ["/.env", "/var/", "**/*.log", "docker-compose.override.yml"]
}
误删 vendor/ 下的目录?别手动删,用 composer clear-cache + install
有人发现 vendor/some/package/tests/ 占地方,就直接 rm -rf vendor/*/tests,结果下次 composer update 又恢复,或者 autoload 错乱。根本原因是:这些目录由包作者定义,不是 Composer “生成”的,删了也没用,还可能破坏完整性校验。
真要精简 vendor,只有两个可靠方式:
- 用
composer install --no-dev跳过 require-dev 里的包(包括它们的 tests/) - 让包作者在
composer.json里配archive.excludes,你才能受益;自己不能替别人删 - 如果某包反复带大量无用文件,考虑换包,或提 PR 帮它加
archive.excludes
为什么 autoload.files 里引入的文件不能被 exclude-from-classmap 排除?
因为 autoload.files 是强制一次性 include,跟 classmap 完全是两套机制。哪怕你在 exclude-from-classmap 里写了那个路径,只要它被 files 列出来了,就会在每次请求时无条件载入。
这容易导致意外执行、重复定义、或环境变量污染(比如 vendor/autoload.php 加载前就跑了个 bootstrap.php):
- 检查
autoload.files数组里有没有不该出现的调试文件、旧兼容层、或全局函数定义 - 这类文件一旦引入,无法通过 exclude 控制;只能删掉引用,或用条件判断包裹逻辑
- CI 环境尤其要注意:本地开发加的
files,上线后可能引发 fatal error
exclude-from-classmap 能屏蔽任意目录,结果发现 vendor 里的东西纹丝不动,或者 PSR-4 自动加载照常工作——它只管 classmap,且只管你主动声明的那一部分。其他路径,Composer 根本不“看”。










