静态页面托管无法替代Composer私有仓库,因其缺乏动态HTTP响应能力,如按Accept头返回JSON、对不存在包返回404而非HTML;必须用Satis生成静态文件并配合正确配置的HTTP服务(如Nginx),或改用type: package手动声明单个包。

不能直接用静态页面托管来当 Composer 私有仓库索引——它缺了最关键的 HTTP 服务端行为,比如响应 POST /packages.json、处理 Accept: application/json 头、返回 404 而非 HTML 错误页。
为什么 packagist.org 模式无法静态化
Composer 官方仓库协议(v2)依赖动态路由和状态码语义:composer install 会向 https://your.repo/p2/vendor/package.json 发起带 Accept 头的 GET 请求,并期望返回 JSON;若包不存在,必须返回 404 状态码,而不是 200 + HTML “页面未找到”。静态托管(如 GitHub Pages、Vercel Static)只做文件映射,不支持按请求头/路径参数返回不同内容或状态码。
可行替代:用 composer/satis 生成静态索引 + 配合简单 HTTP 服务
satis 是官方推荐的轻量私有仓库构建工具,它把所有包元数据预生成为静态 JSON 文件(packages.json、p2/ 目录等),但需要一个能正确响应这些路径的 HTTP 服务——哪怕只是本地 php -S 或 Nginx 的静态文件服务。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 运行
php bin/satis build satis.json web/后,web/目录就是可部署的静态资产 - 部署时必须确保:所有
.json文件返回Content-Type: application/json,且对不存在的p2/xxx.json返回404(不是200+ HTML) - GitHub Pages 默认把
.json当text/plain,需加_headers文件声明 MIME 类型;Vercel 需配置vercel.json中headers规则 - Nginx 示例配置片段:
location ~ .json$ { add_header Content-Type application/json; try_files $uri =404; }
绕过服务端?用 type: package 手动声明单个包
如果只托管一两个内部工具包,根本不需要完整仓库索引。直接在项目 composer.json 的 repositories 里写死包定义:
{
"repositories": [{
"type": "package",
"package": {
"name": "myorg/internal-tool",
"version": "1.0.0",
"dist": {
"url": "https://example.com/releases/internal-tool-1.0.0.zip",
"type": "zip"
},
"autoload": {"psr-4": {"MyOrg\": "src/"}}
}
}],
"require": {"myorg/internal-tool": "^1.0"}
}
这种方式完全静态友好,但无法支持 composer require 自动发现,也不适用多包协作场景。
真正卡住的点从来不是“怎么生成 JSON”,而是 HTTP 状态码和 Content-Type 的精确控制——静态托管平台默认不关心你返回的是不是合法的 Composer API 响应,它只管发文件。

















