答案:卡在“Resolving dependencies”是离线场景下锁文件与vendor目录版本不匹配导致的本地校验死锁,应删vendor和lock、保留composer.json后执行composer install --no-network;若用旧版Composer需提前打包artifact并配置本地仓库。

Composer install 卡在 resolving dependencies 时怎么破?
这是离线场景下最典型的死锁信号,不是网络慢,而是 composer install 在本地 vendor/composer/installed.json 和锁文件 composer.lock 之间反复校验、回退、重试,最终陷入无限循环。根本原因是锁文件里记录的包版本、哈希、源地址与本地可用包不匹配,但 Composer 没法报出明确错误,只是一直 retry。
- 确认是否真离线:运行
composer config --global repo.packagist.org false关闭远程源,再执行composer install --no-plugins --no-scripts,排除插件或脚本干扰 - 强制跳过 lock 文件校验:用
composer install --ignore-platform-reqs --no-install-recommends,但仅限调试,不能用于生产环境 - 检查
composer.lock中每个包的dist.shasum字段是否与你本地vendor/{vendor}/{package}/composer.json或已解压包内容一致,不一致就会触发重下载逻辑(即使离线也会尝试“伪下载”)
离线 vendor 目录和 lock 文件版本不一致怎么办?
常见于从其他机器拷贝 vendor 过来,但没同步 composer.lock,或反过来——composer.lock 是新生成的,而 vendor 是旧版。Composer 会认为“安装不完整”,于是试图补全缺失包,又因无网络而卡住。
- 先删掉
vendor目录和composer.lock,只保留composer.json - 用
composer install --no-network(Composer 2.2+ 支持)强制走离线模式,它会检查vendor是否存在且完整,而不是盲目解析 lock - 如果用的是老版本 Composer(composer archive --format=zip --dir=./offline-pkgs/ 打包依赖,再在目标机用
composer config repositories.offline path ./offline-pkgs+composer install --no-network
自建离线仓库时 packagist.org 的 dist URL 还在生效?
即使配置了本地 path 或 artifact 仓库,Composer 默认仍会读取 composer.lock 里的原始 dist.url(比如 @#@#@#@#@#@#@#@#@#@0...),导致离线时反复失败。
- 运行
composer config --unset repos.packagist彻底禁用默认源 - 在
composer.json中显式声明离线仓库优先级:"repositories": [ { "type": "artifact", "url": "./offline-packages/" }, { "type": "packagist", "enabled": false } ] - 关键一步:修改
composer.lock,把所有包的dist.type改成artifact,dist.url改为相对路径(如./offline-packages/vend/package.zip),否则 Composer 仍按原配置发起 HTTP 请求
为什么 --no-network 不总起作用?
--no-network 只阻止网络请求,不阻止内部依赖图遍历逻辑。如果锁文件中某个包的 require 声明了不存在的版本约束(比如 "monolog/monolog": "^3.0",但本地只有 2.x),Composer 会不断尝试“找一个满足条件的版本”,直到超时或栈溢出。
- 用
composer show --tree(需先有基础 vendor)看实际加载的依赖树,比 lock 文件更真实 - 对关键包,加
--with-dependencies显式指定版本,例如composer require monolog/monolog:2.9.2 --no-update,再composer update monolog/monolog --no-network - 最稳妥的方式:用
composer create-project --no-install生成干净骨架,再手动复制已验证可用的vendor并运行composer dump-autoload -a
离线场景下,Composer 的“确定性”其实高度依赖 lock 文件、vendor 目录、本地仓库三者严格对齐。任何一方被手动改动(比如编辑了 lock 文件、删了部分 vendor 子目录、换了 artifact 包名但没更新 lock),都可能触发隐式重解析逻辑——这个过程没有日志输出,也没有明确报错,只有 CPU 占用缓慢爬升和进程僵死。











