composer archive 不打包软链接依赖,只归档项目真实文件;发布前须删 vendor 并用 composer install --no-dev 拉取真实依赖,确保 composer.lock 中 source.type 为 git 或 zip 而非 path。

composer archive 会忽略软链接,直接打包源码
执行 composer archive 时,它只扫描当前项目目录下的真实文件(按 archive.exclude 规则过滤),不会解析或跟随 vendor/ 下的 symlink。也就是说,哪怕你用 "symlink": true 让 vendor/myorg/my-pkg 指向本地开发路径,archive 打出来的 zip 里依然只有你当前项目的源码,**完全不包含那个被软链接进去的包**——它压根不会读取 vendor/ 目录内容。
想把软链接依赖一起发布,得先让它“落地”
线上环境通常没有开发机的路径、没配 repositories.path、也不允许 symlink(尤其容器或共享主机)。所以发布前必须确保所有依赖都以真实代码形式存在:
- 删掉
vendor/,运行composer install --no-dev(不带--prefer-source),让 Composer 从 Packagist 或私有仓库拉取 tarball 并解压成真实文件 - 如果依赖是内部包且未上私有仓库,必须先把它推到 Git + 注册到 Satis / Private Packagist / 或至少配置好
repositories.composer.json的线上可访问地址 - 检查
composer.lock:确认目标依赖的source字段是type: git或type: zip,而不是type: path
CI/CD 中常见翻车点:缓存导致 symlink 残留
很多 CI 流程会复用 vendor/ 缓存,但缓存里可能还存着本地开发时生成的 symlink。结果就是:composer install 看似成功,实际跑的是旧的、未更新的软链接路径,而 archive 又不打包它——最终线上部署的包既没含依赖,也跑不起来。
解决方法很简单:
- CI 脚本开头加
rm -rf vendor(别信缓存) - 用
composer install --no-cache强制重装 - 上线前加校验:
find vendor/myorg/my-pkg -type l,发现软链接就立刻 fail 构建
真正安全的发布流程:别依赖 archive 做部署包
composer archive 本质是归档源码,不是构建可部署产物。生产环境该用什么?
- 标准做法是:在目标服务器上执行
composer install --no-dev --optimize-autoloader,靠composer.lock锁死版本 - 如果必须上传 zip,则应先
composer install完整生成vendor/,再用zip -r或tar -czf手动打包整个项目目录(含已解压的vendor) - 千万别在
archive后手动 cp vendor 进去——容易漏文件、权限错、autoloader 失效
软链接只该活在开发阶段。一旦进入发布环节,它就该消失。否则你打包的不是代码,是一堆等待报错的假设。


















