composer如何在离线环境中处理依赖的子依赖?

3次阅读

离线安装 composer 报“package not found”主因是子依赖未预下载;须在线执行 composer install –no-dev –prefer-dist 完整构建 vendor 并打包 vendor/、composer.lock、composer.json 三者,离线仅运行 composer install 且禁用 update。

composer如何在离线环境中处理依赖的子依赖?

离线安装时 composer install 报 “Package not found” 怎么办

根本原因不是主包缺失,而是子依赖(transitive dependencies)没被提前下载全。Composer 默认只缓存直接声明在 composer.json 里的包,而像 monolog/monolog 这类被其他包(比如 symfony/console)间接引入的依赖,在离线环境里会直接失败。

实操建议:

  • 在线机器上必须用 composer install --no-dev --prefer-dist 完整跑一次,触发所有子依赖下载并写入 vendor/composer.lock
  • 把整个 vendor/ 目录 + composer.lock + composer.json 一起打包带走,不能只拷 composer.lock
  • 离线机器上禁止运行 composer update 或任何修改锁文件的操作——这会触发网络请求去查包元数据
  • 如果项目用了 platform-configconfig.platform,确保离线环境 PHP 版本和扩展与配置完全一致,否则 composer install 会跳过部分包

如何提前下载所有依赖(含子依赖)到本地供离线使用

composer install 本身做不到“预下载”,它只解压不存档。真正能离线复用的只有两种方式:完整 vendor 打包,或用 composer archive + 自建私库镜像。

实操建议:

  • 首选方案:在线机执行 composer install --no-dev --prefer-dist 后,直接 tar 打包 vendor/ 目录。这是最可靠、兼容性最好的做法
  • 次选方案:用 composer archive 生成 zip 包,但注意它默认只打包当前项目代码,不包含依赖——必须配合 --format=zip --dir=dist 和自定义脚本递归处理 vendor/
  • 不要依赖 composer cache 目录做离线迁移:~/.composer/cache/files/ 里是压缩包,但缺少 composer.lock 中记录的 exact commit hash 和 dist reference,离线时无法校验匹配

composer install 在离线环境报 “Could not parse version constraint”

这不是网络问题,而是 composer.lock 里某个包的 version 字段写的是 dev-master 或带 @dev 的不稳定版本,而离线机没有对应分支信息或 git 配置,导致解析失败。

实操建议:

  • 在线打包前,强制锁定所有版本:运行 composer update --lock,确保 composer.lock 中每个包的 version 是具体语义化版本(如 2.10.0),而非 dev- 前缀
  • 检查 composer.json 是否有 "minimum-stability": "dev""prefer-stable": false,这些配置会让 Composer 主动拉取不稳定版本,离线时必然失败
  • 若必须用 dev 分支,改用 commit hash 显式指定,例如 "monolog/monolog": "dev-main#abc1234",并在在线机上 composer install 后确认该 hash 已写入 composer.lock

私有包(git repo / Satis / Toran)在离线环境怎么处理

私有包不会出现在 packagist.org,离线时 Composer 根本不知道去哪里找。即使你把私有包代码拷进 vendor/composer install 仍会尝试访问原 git URL 校验。

实操建议:

  • 在线机上先用 composer config repositories.<name> path ./path/to/private/pkg</name> 把私有包转成本地路径仓库,再运行 composer update,这样 composer.lock 会记录 "type": "package" 而非 "type": "vcs"
  • 或者手动修改 composer.json,把私有仓库定义改成 {"type": "package", "package": {...}} 形式,并确保 dist.url 指向一个本地可访问的 zip 文件路径(如 file:///tmp/my-pkg.zip
  • 切记:离线机上不能删掉 repositories 配置,否则 Composer 会回退到默认源查找,报 404

最难搞的其实是嵌套的 path 类型仓库——比如 A 包依赖 B 包,B 包又通过 path 引了 C 包。这种情况下,C 包的路径在离线机上大概率不存在,必须提前把三层都 flatten 到同一级目录再打包。

text=ZqhQzanResources