composer archive 命令不存在,官方从未实现;真正有效的 archive 配置仅用于 Packagist 构建流程,通过 composer.json 的 archive.exclude/include 控制打包路径,本地打包应使用 git archive 与 composer install 组合。

composer archive 命令根本不存在,别再试了
执行 composer archive 必然报错:Command "archive" is not defined。Composer 官方从未实现该命令——它只管依赖安装与 autoloader 生成,不处理归档逻辑。你看到的“可用案例”,基本是以下三种之一:
装了第三方插件(如 hirak/php-archive),行为不可控、升级即失效;
在 composer.json 的 scripts 里写了 "archive": "zip -r ...",本质是调用系统 zip;
把 git archive 或 tar 命令误记为 Composer 原生命令。
真正有效的 archive 配置只在 composer.json 的 archive 字段里生效
这个字段只对两种场景起作用:一是你运行 composer archive(但注意:这其实是 composer install --no-dev 后自动触发的 Packagist 构建流程,不是本地命令);二是 Packagist 自动构建 dist 包时读取该配置。它不改变 composer install 行为,也不影响本地开发。
-
archive.exclude是唯一受支持的排除方式,必须写在composer.json根级,格式为数组,路径以/开头表示精确匹配目录(如"/tests"),不支持通配符(**或*.md无效) -
archive.include优先级更高,更推荐:显式列出要打包的路径(如"src/"、"bin/"、"composer.json"),避免 exclude 漏项 - 路径末尾必须带
/才能匹配整个目录("src"≠"src/") -
archive.excludes(带 s)是 Composer 1.x 遗留写法,2.0+ 已废弃,别用
压缩格式和输出路径怎么控制
使用 composer archive(再次强调:这不是本地命令,而是 Packagist 构建环节)时,格式与路径由参数控制,但仅限于 Packagist 环境或自定义脚本中调用:
-
--format=zip生成.zip,--format=tar生成未压缩的.tar;--format=tar不会自动加.gz,需后续手动gzip -
--dir=./releases指定输出目录,该路径必须已存在(不会自动创建父级) -
--file=myapp-v1控制文件名主体,扩展名由--format决定,不用写.zip - 版本号取自
composer.json的version字段,若为空,可能生成dev-前缀名
想本地可靠打包?绕开 archive,用 git archive + composer install 组合
所有“本地一键打包”需求,都应放弃虚构命令,走明确分工链路:
- 只打包源码(发布快照):
git archive --format=zip --output=release-$(jq -r '.version' composer.json).zip HEAD,然后手动cp composer.lock release-*.zip—— 因为git archive默认不包含composer.lock - 打包含 vendor 的可部署包:
composer install --no-dev --optimize-autoloader后,再zip -r deploy.zip . -x "tests/*" ".git/*" "node_modules/*" - 统一触发入口:在
composer.json的scripts中定义,例如:"deploy:package": ["composer install --no-dev --optimize-autoloader", "zip -r dist/app-$(jq -r '.version' composer.json).zip . -x 'tests/*' '.git/*'"],然后运行composer run deploy:package
最容易被忽略的一点:无论用哪种方式,composer.lock 必须进包,否则目标环境无法复现依赖;而 git archive 和大多数 exclude 规则默认把它漏掉——得单独加回。











