PWA 技能用于构建、修复和验证渐进式 Web 应用。其核心问题意识是:这个资源由哪个引擎读取,以及已经安装旧版本的用户会发生什么。
用途与结构 技能分为两部分。第一部分处理 manifest 和安装问题:各引擎行为不同且多次变化,官方文档和模型记忆都可能滞后。第二部分处理缓存和部署问题:PWA 用户常常继续运行昨天的代码,因此每次变更都应以已安装用户群的体验来评判,而非首次访问。
需要丢弃的过时认知 技能列出若干经复现验证的过时观念:Lighthouse 自 12.0.0(2024-04-22)起不再有 PWA 类别,13.5.0 会拒绝 --only-categories=pwa;Safari 在 iOS 15.4+ 且 purpose 为 any 或未设置时会使用 manifest 图标,但 apple-touch-icon 存在时优先;sw.js 的长 Cache-Control 通常不会延迟浏览器更新,因为 updateViaCache 默认 imports 会在每次范围内导航时绕过 HTTP 缓存重新获取,除非 CDN 边缘遵守 max-age/s-maxage 或设置为 updateViaCache: 'all';仅将 /api/ 加入拒绝列表无法阻止其他服务器拥有的导航(如 OAuth/OIDC 回调、服务端渲染路由、webhook、管理页);manifest 可安装不等于完整,缺少 screenshots 时 Chrome 只显示普通安装提示而非更丰富的对话框。
范围边界 技能负责安装、manifest、service worker、离线、更新、客户端推送和商店封装。不覆盖:web-perf(无 service worker 控制下路由的首次加载)、cloudflare-workers-deployments(头部如何在边缘生效)、服务端推送(VAPID 密钥、订阅存储、发送)。
框架接入 推荐前先从仓库检测框架和构建工具。Vite SPA 默认用 vite-plugin-pwa 的 generateSW 和 registerType: 'prompt',需要自定义 fetch 逻辑时用 injectManifest。Next.js 通过 App Router 的 manifest.ts 提供 manifest,缓存用 Serwist(@serwist/next),不应添加已停止维护的 next-pwa 或 @ducanh2912/next-pwa。TanStack Start 的 VitePWA() 配置可能构建成功但把 sw.js 写到 Nitro 不服务的目录,默认采用 SPA 模式配方并断言文件生成位置。Foldkit 在 SSR/SSG 模式下跨构建的 HTML 与 JS 混用会被终态拒绝,因此导航应 NetworkOnly,离线回退使用同一构建 ID 预缓存的页面。技能强调固定版本前先查询最新版本。
通用规则 所有服务器拥有的导航都应从 navigateFallback 中排除;不要对跨域 no-cors 响应做无限制的运行时缓存(Chrome 中每个 opaque 条目可能占用数 MB 配额);sw.js 保持单一稳定 URL 并在 CDN 也设置 Cache-Control: no-cache;每次缓存变更都以已安装用户群为判断基准。
验证方法 Lighthouse 已无 PWA 审计。应构建后运行 node <skill-dir>/scripts/pwa-check.mjs --dir <deployed-output-dir>,部署后可加 --url <origin> 读取头部;退出码 1 表示 FAIL。可在 Chrome DevTools 的 Application > Manifest 中验证可安装性,或在 CI 中用 CDP 的 Page.getInstallabilityErrors。更新验证通过两次部署并观察新 worker 进入 waiting 及提示出现。iOS、Android WebAPK 和商店构建需要真机,并应说明哪些检查已运行、哪些未运行。
参考资料 references 目录包含 manifest、installability、service-workers、updates、toolchain、ios、store、verify 等文档。scripts/check-currency.mjs 用于复查带日期的论断,tests/pwa-check.bats 覆盖检查器,evals/evals.json 保存测试提示。证据标签中 observed 表示在真实构建或稳定浏览器上复现,documented 表示仅来自厂商文档或规范。