composer.json 的 archive.exclude 是唯一官方支持的归档时排除文件的方式,仅影响 ZIP/TAR 打包,路径需以/开头并支持和*通配符,修改后须打新 tag 才生效。

composer.json 的 archive 配置能排除文件
Composer 本身不提供全局“exclude”命令,但打包发布时(如 composer archive 或 Packagist 自动抓取),会读取 composer.json 中的 archive 字段。这是唯一官方支持的、在生成 ZIP/TAR 包时剔除文件的方式。
它只影响归档行为,不影响本地 composer install 或依赖解析。
-
archive必须是对象,不能是布尔值或数组 - 只接受
exclude键,值为字符串数组(支持 glob 模式) - 路径匹配基于包根目录,不是绝对路径
- 不支持正则,仅支持
*和**(后者匹配多级目录)
{
"name": "myvendor/mylib",
"archive": {
"exclude": [
"/tests/",
"/docs/",
"/examples/",
"*.md",
".gitignore",
"phpunit.xml"
]
}
}
别误用 autoload.exclude-from-classmap
这个配置常被当作“排除文件”的捷径,但它实际作用是:在生成 classmap 时跳过指定路径下的类文件,**不删除文件,也不影响包体积**。它只改变自动加载逻辑,对最终发布的 ZIP 包毫无影响。
- 适用于想保留测试类但不让它们进
classmap的场景 - 路径需以
/开头,表示相对于包根目录 - 若你目标是减小上传到 Packagist 的包大小,改这个没用
{
"autoload": {
"psr-4": { "MyVendor\\MyLib\\": "src/" },
"exclude-from-classmap": ["/tests/", "/benchmarks/"]
}
}
Packagist 不执行 .gitattributes 或 .gitignore
很多人尝试用 .gitattributes 的 export-ignore 或 .gitignore 来控制 Composer 发布内容,但 Packagist **完全忽略这些文件**。它只认 composer.json 的 archive.exclude,以及你 Git tag 所指向的 commit 实际包含的文件。
- 如果你的
git archive命令能排除某些文件,那只是本地行为,和 Composer 生态无关 - Packagist 下载的是 Git 仓库中该 tag 对应的完整树(tree),不会运行任何过滤脚本
- 真正有效的做法:确保你要排除的文件不在对应 tag 的 Git 提交里(比如用
git rm --cached+ 提交),或者靠archive.exclude
排除失败的常见原因和验证方式
最常踩的坑是路径写错或没触发归档流程。Packagist 只在你推送新 tag 后自动构建,不会重新打包已存在的版本。
- 修改
composer.json后必须打**新 tag**(如从v1.2.0到v1.2.1),旧版本不会更新 - 路径漏掉开头
/(如写"tests/"而非"/tests/")会导致匹配失败 - 用
composer archive mypkg.zip本地测试时,确认 ZIP 解压后是否真不含那些文件 - Packagist 页面上点 “Download” 得到的 ZIP,才是最终生效的包,务必手动验证
真正起效的只有 archive.exclude + 新 tag。其他所有“排除”手段,要么无效,要么只作用于局部环节。










