Composer archive命令根本不存在,执行必报“Command 'archive' is not defined”;所有可用案例均源于第三方插件或自定义scripts,真正可靠打包需用git archive或composer install配合zip/tar手动归档。

composer archive 命令根本不存在
执行 composer archive 必报错:Command "archive" is not defined。Composer 官方从未实现该命令,所有“能用”的案例都来自第三方插件(如 hirak/php-archive)或项目中自定义的 scripts。这些方案不可靠:插件行为不透明、升级后失效;自定义脚本本质是调用 zip 或 tar,和 Composer 无关。
真正可控的精简打包流程
精简不是靠“排除什么”,而是明确每一步谁负责什么:
- 源码快照(不含
vendor、.git、node_modules):用git archive --format=zip --output=release.zip HEAD,它天然跳过工作区未跟踪文件和.git/目录 - 但注意:
git archive默认不包含composer.lock—— 必须手动加回,否则目标环境无法复现依赖 - 含
vendor的可部署包:先跑composer install --no-dev --optimize-autoloader,再用zip -r deploy.zip . -x "tests/*" ".git/*" "node_modules/*" -
--no-dev不加会导致体积翻倍、引入测试包甚至安全风险;--optimize-autoloader生成autoload_classmap.php,避免运行时扫描路径
archive.exclude 在 composer.json 中为何常失效
这个配置只在**某些第三方插件**中起作用,不是 Composer 原生支持。即使你看到文档说它支持 /tests/ 排除整个目录,实际生效前提是插件已安装且版本匹配。更常见的情况是:
- 写成
"tests/"(无前导斜杠)→ 匹配失败,因为通配符基于项目根目录,必须写"/tests/"或"tests/*" - 想排除
.env却没加进.gitignore→git archive会把它打进去(因它是 tracked 文件) -
vendor/被误认为“被打包”→ 实际是本地未提交的临时文件,或.gitignore规则被覆盖(比如!vendor/autoload.php这类反向规则)
输出路径与格式的硬约束
--dir=./build 要求 build 目录已存在,不会自动创建父级;--file=myapp 不需写扩展名,--format=zip 输出 .zip,--format=tar 输出裸 .tar(不带 .gz)。
最易忽略的一点:如果你用 git archive 打包,而项目没打 tag,又没在 composer.json 里写明 "version" 字段,生成的文件名会是 your-project-dev-xxx.zip——这种命名不利于 CI/CD 自动识别和归档。


















