Composer 不自动排除目录,而是通过 autoload 配置控制加载:未声明的目录不参与自动加载;classmap 用 exclude-from-classmap 排除子目录;autoload-dev 中的路径仅开发时生效。

Composer 默认不会自动排除任何目录,所谓“排除不被加载”,本质是控制 autoload 规则——你没把它加进去,它自然不加载;或者明确告诉 Composer 别扫描它。
composer.json 里没配的目录,根本不会被 autoload
这是最容易被误解的一点:Composer 的自动加载只响应 autoload 或 autoload-dev 下明确声明的规则(如 "psr-4"、"classmap"、"files")。其他目录哪怕在项目里存在,只要没被引用进这些配置,就不会出现在 vendor/autoload.php 的加载链中。
所以“排除”第一步其实是:别往 autoload 配置里加它。
- 检查
composer.json中的"autoload"和"autoload-dev"字段 - 确认没有类似
"App\\": "src/"这种映射意外覆盖了你想排除的子目录(比如"src/Tests/Helper/"被"App\\": "src/"拉进来了) - 如果该目录下有类但你不希望被自动加载,就不要把它放在已声明的命名空间路径下
用 exclude-from-classmap 排除 classmap 扫描结果
当你使用 "classmap" 自动发现类(比如指向整个 lib/ 目录),又想跳过其中某个子目录时,可以用 "exclude-from-classmap"。它只对 classmap 生效,不影响 PSR 规则。
示例:想让 classmap 扫描 src/,但跳过 src/Deprecated/
{
"autoload": {
"classmap": ["src/"],
"exclude-from-classmap": ["src/Deprecated/"]
}
}
-
"exclude-from-classmap"接受路径数组,支持通配符*(如"src/*/Tests/") - 路径是相对于
composer.json的,不是相对于 vendor 或项目根 - 执行
composer dump-autoload后才生效 - 注意:它不阻止文件被其他方式加载(比如手动
require),只影响 classmap 生成的映射表
autoload-dev 中的规则不会进入生产 autoload
如果你只是想让某些目录(比如 tests/、examples/、stubs/)在开发时可用,但完全不出现在生产环境的自动加载中,就该把它们放进 "autoload-dev",而不是 "autoload"。
示例:
{
"autoload": {
"psr-4": {
"MyApp\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"MyApp\\Test\\": "tests/",
"MyApp\\Example\\": "examples/"
}
}
}
- 运行
composer install --no-dev或composer install -o --no-dev时,autoload-dev内容会被忽略 -
vendor/autoload.php在生产模式下不会包含这些路径 - 这比“排除”更干净——是逻辑隔离,不是事后剔除
真正容易被忽略的是:classmap 的 exclude-from-classmap 不影响 PSR 加载,而 PSR 的“排除”只能靠不配、或配得更精确(比如不用宽泛的 "App\\": "src/",改用 "App\\": "src/Domain/")。混用多种 autoload 类型时,得分别处理,不能指望一个配置全局生效。










