composer archive 默认不支持 --no-dev,必须先运行 composer install --no-dev --optimize-autoloader 清理 vendor,再执行 archive;否则会导致 dev 依赖残留、lock 与 vendor 不一致。

composer archive 命令默认不支持排除开发依赖
直接运行 composer archive 会把 vendor/ 下所有已安装的包(包括 require-dev 中的)一起打包进 ZIP,它没有内置的 --no-dev 或类似开关。这是最常被误解的一点——很多人以为它像 install 或 update 那样能控制依赖范围。
正确做法:先清理 vendor,再用 archive 打包
必须分两步走:先确保 vendor/ 里只含生产依赖,再调用 archive。否则打包结果不可控。
- 运行
composer install --no-dev --optimize-autoloader,强制重装并剔除require-dev包 - 确认
vendor/已精简(可检查vendor/bin/是否还残留 phpunit、phpcs 等工具) - 再执行
composer archive --format=zip --file=myapp.zip
注意:--optimize-autoloader 不是可选,它能生成更小的 autoload_classmap.php,对部署包体积和加载性能都有帮助。
替代方案:用 zip 命令手动打包更可控
如果项目结构复杂(比如含 node_modules、.git、缓存目录),或你想跳过 composer archive 的路径限制(它只打包当前项目根目录及 vendor/),直接用系统命令更灵活:
rm -rf vendor composer install --no-dev --optimize-autoloader zip -r myapp.zip \ . \ -x "*/.git/*" \ -x "*/node_modules/*" \ -x "*/vendor/bin/*" \ -x "phpunit.xml*" \ -x "phpcs.xml*"
这个命令显式排除了常见干扰项,且不会误打包未提交的临时文件。Windows 用户可用 7z 或 PowerShell 的 Compress-Archive 替代。
容易忽略的关键点
composer archive 默认会把 composer.lock 和 composer.json 一起打进 ZIP,但不会验证它们是否与当前 vendor/ 一致——如果你跳过了 install --no-dev 这步,lock 文件里仍记录着 dev 包,而实际 vendor 里没有,部署时可能出错。
真正安全的发布包,必须保证三者同步:composer.json(不含 dev)、composer.lock(由 --no-dev install 生成)、vendor/(仅含 lock 中列出的生产包)。










