根本原因是本地仓库元数据缺失,特别是require字段未导出,导致Composer误判包无子依赖;需检查satis.json配置、启用providers和require-dependencies,并验证packages.json中是否存在require字段。

composer install 本地包不装子依赖,根本不是网络问题
这问题几乎全因本地仓库元数据缺失——composer install 看到的 packages.json 里没有 require 字段,就默认“这个包不依赖任何东西”,于是 laravel/framework 装了,illuminate/support 却直接跳过。Satis 默认不解析 ZIP 包内的 composer.json,只读你 satis.json 里硬写的字段。
检查方式很简单:打开你的私有仓库首页(比如 https://repo.example.com/packages.json),搜索目标包名,看返回的 JSON 里有没有 "require": { ... }。如果没有,就是配置漏了。
- 确认
satis.json中启用了"providers": ["*"],且没加"only": [...]过滤掉关键字段 - 补全
"require-dependencies": true(Satis ≥2.0)或在repositories配置中显式声明"type": "package"并手动写入require - 生成后用
curl -s https://repo.example.com/packagist/vendor/package-name.json | jq '.require'验证字段是否真实存在
报 “Package is not installed” 却明明写了 require
这不是包没下下来,是 vendor/ 目录里真没这个目录——常见于 composer.lock 和 composer.json 不一致,或安装中途被 Ctrl+C 中断。别急着重装,先盯住三件事:
-
composer.lock文件必须存在且已提交到 Git;如果它被忽略或丢失,composer install会退化成composer update,结果不可控 - 报错包名(如
myorg/my-local-package)是否准确写在composer.json的require或require-dev里?注意末尾空格、单双引号混用、路径拼写错误(比如写成myorg/my-local-package:多了个冒号) - 运行
composer show myorg/my-local-package:如果输出no such package,说明它根本没进 Composer 解析树——大概率是本地仓库没同步该包,或type设成了vcs却没打 tag
为什么 composer why-not 查不到本地包的阻塞链
composer why-not 依赖远程元数据源,而本地包若未正确注册进仓库索引,Composer 就当它不存在。你运行 composer why-not myorg/my-local-package:1.0.0 返回空,不代表没问题,只代表 Composer 根本没看到这个包。
验证方法分两步:
- 先确认该包能否被发现:
composer search my-local-package,若无结果,说明仓库没收录或name字段写错 - 再查它是否被其他包间接拉入:
composer depends --tree myorg/my-local-package,如果也为空,说明没人 require 它,或者它的autoload没配对,导致自动加载失败但不报错 - 最直接的方式是临时切回 Packagist:
composer config --global repo.packagist composer https://packagist.org,再跑why-not—— 如果这时能出结果,就坐实是本地仓库元数据问题
本地包 require 其他私有包却始终不装
这是典型的“嵌套本地依赖”陷阱:A 包 require B 包,B 包又 require C 包,但 Satis 只导出了 A 的元数据,B 和 C 的 require 字段全丢了。Composer 解析 A 时发现“B 不依赖 C”,自然跳过。
修复必须从仓库侧入手,不能靠改项目 composer.json:
- 确保所有被依赖的本地包(B、C)都已推送到对应 VCS 仓库,并打了符合
minimum-stability的 tag(如v1.0.0) - Satis 配置中,
repositories列表要包含全部相关仓库,不能只写 A 的;否则它连 B 的composer.json都读不到 - 强制重刷元数据:
php bin/satis build satis.json web/ --skip-errors --no-interaction,加--verbose看它是否提示 “Skipping package B: no version found”
真正容易被忽略的是:Satis 构建过程不会报错退出,即使某个包因权限、网络或格式问题没导出成功,它只是静默跳过——你得手动翻 web/packages.json 或构建日志确认每个包的 require 字段是否完整。


















