mcpField
P
pwa-expert

pwa-expert

github.com/curiositech开发257546 次安装2 天前更新
代码仓库

关于 pwa-expert

用于构建可安装、支持离线使用的渐进式 Web 应用开发 Skill,涵盖清单、Service Worker 缓存、安装提示、后台同步和更新流程,也介绍 Next.js 方案。

主要功能

  1. 01配置 Web App Manifest
  2. 02注册 Service Worker 并设置缓存
  3. 03处理安装提示
  4. 04离线回退与状态模式
  5. 05后台同步与更新流程
  6. 06Next.js PWA 方案

适用场景

  1. 01让 Web 应用可安装
  2. 02缓存资源以供离线使用
  3. 03将操作排队并在联网后执行
  4. 04通知用户应用有可用更新

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/curiositech/some_claude_skills --skill pwa-expert

安装后在 Claude Code 中输入/pwa-expert确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.claude-plugin/
plugin.json
references/
nextjs-integration.md
service-worker-patterns.md
background-sync.md
install-prompt.md
update-flow.md
offline-handling.md

详细介绍

渐进式 Web 应用专家

使用 Service Worker、智能缓存和类原生体验,构建可安装、支持离线的 Web 应用。

何时使用此技能

  • 让 Web 应用可在移动端/桌面端安装
  • 实现离线功能
  • 设置 Service Worker 缓存策略
  • 处理安装提示(beforeinstallprompt)
  • 为离线优先应用实现后台同步
  • 管理 PWA 更新流程
  • 创建 Web 应用清单

何时不使用此技能

  • 原生应用开发 → 使用 React Native、Flutter 或原生 SDK
  • 通用 Web 性能优化 → 使用 Lighthouse/性能审计工具
  • 服务端渲染问题 → 查阅 Next.js/框架专用文档
  • 仅需推送通知 → 考虑专用推送通知服务
  • 简单静态网站 → PWA 的额外开销可能不值得

核心概念

PWA 可安装的条件
  1. HTTPS(开发环境可使用 localhost)
  2. 包含必需字段的 Web 应用清单
  3. 带有 fetch 处理程序的 Service Worker
  4. 图标(最小尺寸为 192×192 和 512×512)
PWA 技术栈
┌─────────────────────────────────────────┐
│           Your App (React/Next.js)      │
├─────────────────────────────────────────┤
│         Service Worker (sw.js)          │
│  ┌─────────────┐  ┌─────────────────┐   │
│  │   Cache     │  │  Network Fetch  │   │
│  │   Storage   │  │    Handling     │   │
│  └─────────────┘  └─────────────────┘   │
├─────────────────────────────────────────┤
│          manifest.json                  │
│  (App identity, icons, display mode)    │
└─────────────────────────────────────────┘

Web 应用清单

完整的 manifest.json
{
  "name": "Junkie Buds 4 Life",
  "short_name": "JB4L",
  "description": "Recovery support app",
  "start_url": "/",
  "scope": "/",
  "display": "standalone",
  "orientation": "portrait-primary",
  "background_color": "#1a1410",
  "theme_color": "#1a1410",
  "icons": [
    {
      "src": "/icons/icon-192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/icons/icon-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/icons/icon-maskable-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    }
  ],
  "shortcuts": [
    {
      "name": "Find Meetings",
      "short_name": "Meetings",
      "url": "/meetings?source=shortcut",
      "icons": [{ "src": "/icons/meetings-96.png", "sizes": "96x96" }]
    }
  ]
}
显示模式
模式描述
fullscreen无浏览器界面,全屏显示
standalone类似应用的体验,无 URL 栏(推荐)
minimal-ui显示部分浏览器控件
browser普通浏览器标签页
在 HTML 中添加链接
<head>
  <link rel="manifest" href="/manifest.json" />
  <meta name="theme-color" content="#1a1410" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
  <link rel="apple-touch-icon" href="/icons/apple-touch-icon.png" />
</head>

Service Worker 基础知识

注册
// lib/pwa.ts
export async function registerServiceWorker() {
  if ('serviceWorker' in navigator) {
    try {
      const registration = await navigator.serviceWorker.register('/sw.js', {
        scope: '/',
      });
      return registration;
    } catch (error) {
      console.error('SW registration failed:', error);
    }
  }
}

// Call on app mount
useEffect(() => {
  registerServiceWorker();
}, []);
Service Worker 基本结构
// public/sw.js
const CACHE_NAME = 'myapp-v1';
const STATIC_ASSETS = ['/', '/offline', '/manifest.json'];

// Install: Cache static assets
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => cache.addAll(STATIC_ASSETS))
  );
  self.skipWaiting();
});

// Activate: Clean old caches
self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then((keys) =>
      Promise.all(keys.filter((k) => k !== CACHE_NAME).map((k) => caches.delete(k)))
    )
  );
  self.clients.claim();
});

// Fetch: Handle requests (see references for strategies)
self.addEventListener('fetch', (event) => {
  event.respondWith(handleFetch(event.request));
});

参见: references/service-worker-patterns.md,了解缓存策略实现

缓存策略

策略适用场景权衡
Cache-First静态资源、字体、图片缓存更新前内容会过时
Network-FirstAPI 数据、用户内容速度较慢,需要网络连接
Stale-While-Revalidate兼顾内容新鲜度和速度在后台更新
Network-Only身份验证、实时数据不支持离线
Cache-Only版本化资源永不更新

参见: references/service-worker-patterns.md,查看完整实现

安装提示

处理 beforeinstallprompt 事件,以显示自定义安装界面:

// Basic pattern
const [deferredPrompt, setDeferredPrompt] = useState(null);

useEffect(() => {
  window.addEventListener('beforeinstallprompt', (e) => {
    e.preventDefault();
    setDeferredPrompt(e);
  });
}, []);

const handleInstall = async () => {
  if (deferredPrompt) {
    deferredPrompt.prompt();
    const { outcome } = await deferredPrompt.userChoice;
    // outcome: 'accepted' or 'dismissed'
  }
};

参见: references/install-prompt.md,了解完整的 usePWAInstall hook 和组件

离线体验

关键模式:

  • 导航失败时回退到离线页面
  • 使用 useOnlineStatus hook 检测网络连接
  • 显示离线横幅,告知用户当前状态

参见: references/offline-handling.md,查看实现方式

后台同步

离线时将操作加入队列,在网络连接恢复后执行:

// In Service Worker
self.addEventListener('sync', (event) => {
  if (event.tag === 'sync-data') {
    event.waitUntil(syncPendingData());
  }
});

// In App - trigger sync
const registration = await navigator.serviceWorker.ready;
await registration.sync.register('sync-data');

参见: references/background-sync.md,了解完整的 IndexedDB 集成

更新流程

在有新版本可用时通知用户:

// Basic pattern
registration.addEventListener('updatefound', () => {
  const newWorker = registration.installing;
  newWorker?.addEventListener('statechange', () => {
    if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
      // New version available - show update prompt
    }
  });
});

参见: references/update-flow.md,了解 usePWAUpdate hook 和更新策略

Next.js 集成

Next.js PWA 的选项:

  1. next-pwa - 适用于标准 Next.js 服务端
  2. 自定义 SW - output: 'export'(静态网站)时必需
  3. Workbox CLI - 在构建后生成 SW

参见: references/nextjs-integration.md,了解详细配置

快速参考

任务解决方案
检查是否已安装window.matchMedia('(display-mode: standalone)').matches
强制更新 SWregistration.update()
清除所有缓存caches.keys().then(keys => keys.forEach(k => caches.delete(k)))
检查网络状态navigator.onLine
获取 SW 注册信息navigator.serviceWorker.ready
跳过等待在 SW 中调用 self.skipWaiting()
接管控制权在 SW 中调用 self.clients.claim()

测试 PWA

Chrome DevTools
  1. Application 标签页 → Manifest、Service Workers、Cache Storage
  2. Lighthouse → PWA 审计
  3. Network → 勾选 Offline 复选框进行模拟
调试清单
  • 清单已加载(应用 → 清单)
  • SW 已注册(应用 → 服务工作线程)
  • 缓存已填充(应用 → 缓存存储)
  • 安装提示已触发(在控制台中检查 beforeinstallprompt)
  • 离线页面可用(网络 → 离线)
  • 更新流程可用(触发更新,验证提示)

参考资料

/references/ 中的详细实现:

  • service-worker-patterns.md - 缓存策略实现
  • install-prompt.md - usePWAInstall hook 和安装组件
  • offline-handling.md - 离线页面、状态 hook 和横幅
  • background-sync.md - 使用 IndexedDB 的后台同步
  • update-flow.md - 更新检测和用户提示
  • nextjs-integration.md - Next.js PWA 配置选项

评论

支持 Markdown