
使用 Composer 本地仓库(如 Satis)时,若仅安装 require/require-dev 中声明的顶层包而忽略其深层依赖,根本原因在于仓库元数据不完整——Satis 未从包内 composer.json 自动提取依赖信息,必须显式在 satis.json 中补全 require、autoload、conflict、replace、provide、suggest 等关键字段。
使用 composer 本地仓库(如 satis)时,若仅安装 `require`/`require-dev` 中声明的顶层包而忽略其深层依赖,根本原因在于仓库元数据不完整——satis 未从包内 `composer.json` 自动提取依赖信息,必须显式在 `satis.json` 中补全 `require`、`autoload`、`conflict`、`replace`、`provide`、`suggest` 等关键字段。
当你将本地仓库(例如通过 Satis 搭建)配置进 composer.json:
"repositories": [
{ "type": "composer", "url": "http://localhost/" }
]并执行 composer install 后,Composer 不会像访问 Packagist 那样自动递归解析每个包的 composer.json 中声明的 require 字段。相反,它完全依赖于 Satis 生成的仓库元数据(packages.json) ——而该文件的内容,由你的 satis.json 配置决定。
⚠️ 关键误区:很多人误以为只要包 ZIP 文件中包含正确的 composer.json,Satis 就会自动读取并注入依赖关系。但事实是:Satis 默认仅提取极简元数据(如 name、version、dist),除非你明确在 satis.json 中启用并配置了完整的“root-level”字段映射。
✅ 正确做法:确保 satis.json 中为每个包(或全局 archive 配置)启用并同步以下核心字段:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
{
"name": "my/private-repo",
"homepage": "http://localhost/",
"repositories": [
{ "type": "vcs", "url": "https://github.com/myorg/package-a" }
],
"require-all": true,
"output-dir": "web/",
"archive": {
"directory": "dist",
"format": "zip",
"skip-dev": false,
"absolute-directory": false
},
"providers": {
"laravel/framework": {
"require": {
"php": "^8.0",
"ext-json": "*",
"illuminate/contracts": "^9.0",
"symfony/console": "^6.0"
},
"autoload": { "psr-4": { "Illuminate\": "src/Illuminate/" } },
"conflict": { "laravel/installer": "<4.0" },
"replace": { "illuminate/support": "self.version" },
"provide": { "psr/container-implementation": "1.0" },
"suggest": { "aws/aws-sdk-php": "Required to use the SQS queue driver." }
}
}
}? 更推荐方式(自动化):使用 "require-all": true 并配合 --skip-errors 运行 Satis 构建,同时通过脚本预扫描所有包的 composer.json,动态提取上述字段写入 satis.json 或生成 packages.json 的扩展元数据。示例 PHP 扫描逻辑片段:
foreach ($packages as $package) {
$pkgJson = json_decode(file_get_contents($package . '/composer.json'), true);
$meta = array_filter([
'require' => $pkgJson['require'] ?? [],
'autoload' => $pkgJson['autoload'] ?? [],
'conflict' => $pkgJson['conflict'] ?? [],
'replace' => $pkgJson['replace'] ?? [],
'provide' => $pkgJson['provide'] ?? [],
'suggest' => $pkgJson['suggest'] ?? [],
]);
// 写入 satis.json 的 providers 或用于生成 packages.json
}? 注意事项:
-
satis.json中缺失require字段 → Composer 认为该包“无依赖”,导致illuminate/contracts、symfony/console等 Laravel 核心依赖不被安装,从而触发Class "IlluminateFoundationApplication" not found错误; -
autoload缺失 → 类无法自动加载,即使包已安装也会报Class not found; -
conflict/replace/provide虽非必需,但缺失可能导致版本冲突检测失效或插件兼容性异常; - 建议始终运行
satis build satis.json --no-interaction后,检查输出目录下的packages.json,确认目标包对象中是否包含"require"等字段及其内容是否完整。
✅ 验证修复效果:
构建完成后,清空项目 vendor/ 和 composer.lock,执行:
composer clear-cache composer install -vvv
观察日志中是否开始解析并下载 illuminate/*、symfony/* 等子依赖 —— 若成功,即表明元数据已正确注入。
总结:Composer 本地仓库不是“透明代理”,而是“元数据服务”。它的行为完全取决于你提供的 satis.json(或 Private Packagist 等替代方案的配置)。宁可多导出字段,不可少;宁可脚本自动化,不可手动遗漏。

















