diff --git a/README.md b/README.md index 635d9ea..5e500f0 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ ## 开发环境 -| 开发者类型 | 需要自行准备 | 说明 | -| --- | --- | --- | -| 普通开发者 | [Vite+](https://viteplus.dev/) 的 `vp` CLI | 进入仓库后执行 `vp install`,其余项目工具由仓库管理 | -| 真实接口验证者 | 浙江大学校园网或代理、CC98 账号 | 账号写入 `.cc98-credentials.local`;普通构建和离线测试不需要 | +| 开发者类型 | 需要自行准备 | 说明 | +| ------------------ | ----------------------------------------------------------- | ------------------------------------------------------------------------- | +| 普通开发者 | [Vite+](https://viteplus.dev/) 的 `vp` CLI | 进入仓库后执行 `vp install`,其余项目工具由仓库管理 | +| 真实接口验证者 | 浙江大学校园网或代理、CC98 账号 | 账号写入 `.cc98-credentials.local`;普通构建和离线测试不需要 | | 并行或自动化开发者 | [Worktrunk](https://worktrunk.dev/);按需安装浏览器运行环境 | Worktrunk 用于多 worktree;浏览器环境运行 `vp exec agent-browser install` | -| 部署维护者 | Vercel 项目权限;按需安装 Vercel CLI | 普通开发者不需要;生产域名维护还需要相应 DNS 权限 | +| 部署维护者 | Vercel 项目权限;按需安装 Vercel CLI | 普通开发者不需要;生产域名维护还需要相应 DNS 权限 | 安装依赖并启动开发环境: @@ -52,7 +52,7 @@ vp run ready # format + lint + typecheck + test + build ## 测试部署 -测试站部署在 Vercel,项目根目录保持为仓库根目录。Vercel 会按 `vercel.json` 构建主站及其传递依赖,并发布 `apps/website/dist`。主站源码、静态资源、API 契约源码、UBB 或相关构建配置发生变化时才会部署;测试、探测数据、生成文档和 README 等非构建输入不会触发主站部署。Vue Router 使用 history 模式,所有未命中静态文件的请求都会回退到 `index.html`。 +测试站部署在 Vercel,项目根目录保持为仓库根目录。Vercel 会按 `vercel.json` 构建主站及其传递依赖,并发布 `apps/website/dist`。主站源码、静态资源、API 契约源码、UBB 或相关构建配置发生变化时才会部署;测试、探测数据、生成文档和 README 等非构建输入不会触发主站部署。Vue Router 使用 history 模式,只有业务路由未命中时回退到 `index.html`;缺失静态资源、Service Worker、Manifest 和固定 PWA 文件保留真实错误响应。 用户文档使用独立的 Vercel 项目 `cc98-docs`,根目录是 `apps/docs`。只有文档内容、文档站配置、静态资源或相关依赖发生变化时才部署文档站。PR 会生成文档预览,`main` 分支发布到 `https://cc98-docs.vercel.app`。 diff --git a/apps/docs/content/guide/getting-started.md b/apps/docs/content/guide/getting-started.md index a573e58..18e42bf 100644 --- a/apps/docs/content/guide/getting-started.md +++ b/apps/docs/content/guide/getting-started.md @@ -12,7 +12,7 @@ 支持 PWA 的浏览器可以把 CC98 安装到桌面或主屏幕。安装入口通常位于地址栏或浏览器菜单中,名称可能是“安装应用”“添加到主屏幕”或“创建快捷方式”。安装后会以独立窗口打开,账号和外观设置仍由当前浏览器管理。 -页面提示新版本已经准备好时,点击“刷新”即可切换版本。选择“稍后”不会影响当前页面,下次发现更新时还会再次提示。 +页面提示新版本已经准备好时,点击“立即更新”即可切换版本。选择“稍后”不会影响当前页面,下次发现更新时还会再次提示。如果页面显示“页面资源加载失败”,说明目标页面所需资源没有加载成功,可能是网络波动或网站刚刚更新。联网后点击“重新加载”即可重试。重新加载前,请先保存尚未提交的内容。 ## 认识顶部导航 diff --git a/apps/website/build/runtime-cache.ts b/apps/website/build/runtime-cache.ts new file mode 100644 index 0000000..b84fe03 --- /dev/null +++ b/apps/website/build/runtime-cache.ts @@ -0,0 +1,45 @@ +interface AppAssetResponseContext { + request: Request; + response: Response; +} + +function validateAppAssetResponse({ request, response }: AppAssetResponseContext): Response | null { + if (response.status !== 200) return null; + + const contentType = response.headers.get("Content-Type")?.toLowerCase() ?? ""; + const pathname = new URL(request.url).pathname.toLowerCase(); + + if (pathname.endsWith(".js")) { + return contentType.includes("javascript") || contentType.includes("ecmascript") + ? response + : null; + } + if (pathname.endsWith(".css")) { + return contentType.startsWith("text/css") ? response : null; + } + if (/\.(?:woff2?|ttf)$/.test(pathname)) { + return contentType.startsWith("font/") || + contentType.startsWith("application/font-") || + contentType.startsWith("application/x-font-") || + contentType.startsWith("application/octet-stream") + ? response + : null; + } + return null; +} + +export function createAppAssetCachePlugin() { + const cacheWillUpdate = async (context: AppAssetResponseContext): Promise => + validateAppAssetResponse(context); + + const cachedResponseWillBeUsed = async (context: { + request: Request; + cachedResponse?: Response; + }): Promise => { + const { request, cachedResponse } = context; + if (!cachedResponse) return null; + return validateAppAssetResponse({ request, response: cachedResponse }); + }; + + return { cacheWillUpdate, cachedResponseWillBeUsed }; +} diff --git a/apps/website/src/components/PwaStatusBanner.vue b/apps/website/src/components/PwaStatusBanner.vue index 31a1a70..91b052c 100644 --- a/apps/website/src/components/PwaStatusBanner.vue +++ b/apps/website/src/components/PwaStatusBanner.vue @@ -1,27 +1,90 @@