Skip to content

页间 · Pagehaven:一次真实主流程 ​

维护者更新作品元数据和文字层后,希望发布一个浏览器能直接打开的阅读站。这里沿静态构建和发布交接解释数据怎样进入页面,以及为什么页面、检索库和发布清单必须来自同一次构建。

下面的 case 是依据源码分支整理的代表性输入与结果,不是本轮线上观测。

输入或状态动作与结果
空内容模板允许构建;没有章节路由,仍保留其余站点页面
同一内容、清单与检索库站点能读取匹配的检索指针
内容或域名与检索清单不同build:site 拒绝,需完整重建
无对象存储凭据的 dry-run图片在线核对标为未校验
业务产物有 2,000 个静态文件,目标为 ESA 或 all加上 1 个部署验证预留后超过 ESA 的 2,000 文件上限,发布检查在上传前拒绝
Workers 或 ESA 命令成功,验证入口却返回其他平台或上一次部署的内容随机验证文件不匹配,不记录成功回执,不启用共享生产指针

Step 1: 把配置和内容固定为一次构建输入 ​

维护者在站点配置和 data 中描述内容。完整构建先生成平台配置,再读取作品树生成清单。清单记录版本、页面地址和图片 key;没有凭据时对象存储核对会跳过并标明未校验,这不能解释为图片已在线验证。

检索库前缀也在此时验证:db/、search-v2/ 等安全 ASCII 相对目录可用,中文、空格、URL 转义、空段及点段在构建前拒绝。配置、发布计划和浏览器加载共用同一契约,避免发布了浏览器无法使用的对象路径。

对应实现(仓库文件:scripts/build-manifest.mjs),定位 buildManifest、verifyOnly、MISSING_FILE。

Step 2: 给检索库绑定相同版本 ​

文字与元数据进入可在浏览器使用的 SQLite 检索库。建库步骤核对已有清单的版本和内容指纹,写出带版本的库及分块清单,再把数据库指针回填发布清单。跳过版本核对会让页面指向另一批缓存字节,所以同名发布对象不能任意覆盖。

对应实现(仓库文件:scripts/build-db.mjs),定位 readManifest、resolveVersion、galleryFingerprint。

Step 3: 每话生成一个可直接浏览的页面 ​

站点步骤先检查静态跳转来源是否为规范路径、目标是否仍在输出根目录内,再把内容写入生成目录并调用 Astro 构建。不安全路径会在修改生成文件及清理旧产物之前报错。空内容模板仍会生成其余页面;有内容时每话页面承载页面列表与文字层。若检索清单的指纹、域名或明确发布版本与站点不一致,步骤会在生成前报错,要求重新执行完整构建。

对应实现(仓库文件:scripts/build-site.mjs),定位 writeSiteGalleryJson、manifest.sourceSha256 检查、astro build。

Step 4: 补齐静态托管需要的文件 ​

构建随后写出索引和 sitemap,并按开关放入可公开的响应配置。关闭平台配置时仍保留纯静态基线;GitHub Pages 的兜底文件和必要的静态跳转页由站点步骤生成,跳转页对语言属性和目标地址统一转义。所有目标使用相同的静态输出边界检查。图片与数据库不应混入站点 HTML 产物,它们有独立发布位置。

Workers 和 ESA 的部署控制模板也由配置生成,但不复制进 dist。模板不含项目身份;部署时才从 secrets 注入名称和实际产物目录。这样托管平台得到的是同一份静态站点,而公开页面不会暴露部署控制文件。Workers 仍使用 Static Assets,搜索仍在浏览器执行。

对应实现(仓库文件:scripts/build-site.mjs),定位 GENERATED_FILES、.nojekyll、metaRefresh。

Step 5: 用预算与真实构建约束结果 ​

维护检查守住文件数、单文件大小、每话 HTML、配置同步等约束。选择发布目标后,还会按该目标检查静态产物预算;all 需要同时满足四端预算。Workers 与 ESA 额外预留 1 个文件和 4,096 字节供部署验证,所以默认业务产物上限分别为 17,999 和 1,999 文件。ESA 的总大小检查也包括这份字节预留;文件数还要计入章节以外的页面和资源,不能解释成可容纳 1,999 话。集成测试会用最小夹具走实际构建,也会触及共享生成目录。

同一检查入口还核对双语 README 的章节链接。修改标题后,导航参数必须同步到 CNB 生成的锚点,例如 Getting started 使用 #getting-started;旧的 #section-1 或错误大小写会导致检查失败。

对应实现(仓库文件:scripts/test/site-build.test.mjs),定位 CONFIG_FILE / DATA_DIR / DIST_DIR / OUT_DIR、run。

Step 6: 核对部署目标再启用生产版本 ​

发布由 CNB 手动按钮或 GitHub Actions 的手动发布工作流触发,两端共用同一套构建、部署与启用脚本。all 展开为 Makers、ESA、GitHub Pages 和 Workers,旧的 Cloudflare Pages 保留为单独的 cloudflare 目标。GitHub 尚无独立预览环境,因此 preview 搭配 github 或 all 会提前拒绝。Workers 使用独立预览名称和地址;ESA 使用 staging,CI 验证请求单独将正式域名解析到控制台测试 IP,保留 Host、SNI 和证书校验,不改系统 hosts。预览始终不启用生产指针。

部署脚本先用本地 release.json 核对产物与构建清单。Workers 和 ESA 随后各自创建临时上传副本,并在其中写入一个随机命名的验证文件,记录本次随机值、目标、版本、指纹与环境。即使内容版本相同,重试也会产生新随机值。验证文件不含账号、项目名或凭据,且不写回共享 dist 或归档;支持写时复制的文件系统可复用原文件数据块,其他系统使用普通复制。

CLI 成功后,脚本从所配 HTTPS 根地址读取本次随机文件,拒绝重定向,并逐项核对内容。另一个平台的共用 release.json、其他目标的证明和上次部署的证明都不能替代它。因此验证地址必须实际到达本次目标;共享域名仍指向 Makers 时,不能用于确认备用 Workers 或 ESA。ESA staging 的请求和连接器来自同一 Undici 包,避免 Node 内置请求接口与依赖版本不兼容。所有选定目标的成功回执匹配本次构建后,发布流程才以条件写入移动共享指针。

如果第二个平台失败,前面成功的平台可能已经更新;共享指针保持原样不代表跨平台回滚。页面绑定本次构建的检索库版本,旧页面也继续读取自己的版本。真实平台能否访问、CDN 跨域和套餐资格仍需单独验收;当前流程不改变域名根路径假设,不支持 GitHub 项目站的 /仓库名/ 子路径。

部署交接(仓库文件:scripts/deploy.mjs)、随机验证文件(仓库文件:scripts/lib/deploy-proof.mjs)、线上核对(仓库文件:scripts/lib/deploy-ready.mjs)、条件启用(仓库文件:scripts/lib/release.mjs)是这一步的源码入口。

检查这条解释 ​

sh
npm run check
npm test
npm run build

构建与测试可能写入共享生成目录,执行前需保护已有工作。各轮实际命令结果见同步记录,源码静态确认、本地测试和云端部署分别记账。平台适配仍需按根规则另做真实预览部署;本地通过不表示站点已经上线。

理解这条交接后,用代码地图定位下一次修改;需要反查依据时查看源码调查与边界证据。

证据状态:除特别标注外,本页基于当前源码已确认。