mcpField
P
pwa

pwa

github.com/claude-dev-suite開発4642 回インストール2 日前に更新
リポジトリ

pwa について

インストール可能でオフライン動作に対応するプログレッシブ Web アプリの開発者向けリファレンススキルです。マニフェスト、Workbox のサービスワーカー、キャッシュ戦略、インストールプロンプトを解説します。

主な機能

  1. 01Web App Manifest の設定
  2. 02Workbox サービスワーカーのパターン
  3. 03オフラインフォールバックの処理
  4. 04キャッシュ戦略の選択
  5. 05インストールプロンプトの処理
  6. 06本番環境向けチェックリスト

活用シーン

  1. 01Web アプリへのオフラインアクセス追加
  2. 02静的アセットと動的データの適切なキャッシュ
  3. 03アプリのインストールプロンプトの実装

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill pwa

インストール後、Claude Code で/pwaを入力して読み込まれたか確認します。

詳細

プログレッシブウェブアプリ

ウェブアプリマニフェスト

{
  "name": "My App",
  "short_name": "MyApp",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#000000",
  "icons": [
    { "src": "/icons/192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icons/512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
  ]
}
<link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" href="/icons/192.png" />

サービスワーカー(Workbox — 推奨)

// sw.ts (using Workbox)
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';

// Precache app shell
precacheAndRoute(self.__WB_MANIFEST);

// Cache-first for static assets
registerRoute(
  ({ request }) => request.destination === 'image' || request.destination === 'font',
  new CacheFirst({
    cacheName: 'static-assets',
    plugins: [new ExpirationPlugin({ maxEntries: 100, maxAgeSeconds: 30 * 24 * 60 * 60 })],
  })
);

// Network-first for API calls
registerRoute(
  ({ url }) => url.pathname.startsWith('/api/'),
  new NetworkFirst({
    cacheName: 'api-cache',
    plugins: [new ExpirationPlugin({ maxEntries: 50, maxAgeSeconds: 5 * 60 })],
  })
);

// Stale-while-revalidate for pages
registerRoute(
  ({ request }) => request.mode === 'navigate',
  new StaleWhileRevalidate({ cacheName: 'pages' })
);

登録

if ('serviceWorker' in navigator) {
  window.addEventListener('load', async () => {
    const registration = await navigator.serviceWorker.register('/sw.js');
    console.log('SW registered:', registration.scope);
  });
}

オフライン時のフォールバック

// In service worker
import { setCatchHandler } from 'workbox-routing';

setCatchHandler(async ({ event }) => {
  if (event.request.destination === 'document') {
    return caches.match('/offline.html');
  }
  return Response.error();
});

キャッシュ戦略

戦略用途鮮度
キャッシュ優先静的アセット、フォント、画像古くても可
ネットワーク優先API データ、動的ページ新しいデータを優先
古いキャッシュを使用しながら再検証半動的なコンテンツ古いデータを使用し、更新
ネットワークのみ認証、POST リクエスト常に最新
キャッシュのみ事前キャッシュされたアプリシェル不変

インストールプロンプト

let deferredPrompt: BeforeInstallPromptEvent | null = null;

window.addEventListener('beforeinstallprompt', (e) => {
  e.preventDefault();
  deferredPrompt = e;
  showInstallButton();
});

async function installApp() {
  if (!deferredPrompt) return;
  deferredPrompt.prompt();
  const { outcome } = await deferredPrompt.userChoice;
  console.log(`Install ${outcome}`);
  deferredPrompt = null;
}

避けるべきパターン

避けるべきパターン修正方法
Cache First ですべてをキャッシュする動的データには Network First を使用する
オフライン時のフォールバックページがないoffline.html を事前キャッシュする
キャッシュの有効期限がないmaxEntries/maxAge を指定して ExpirationPlugin を使用する
サービスワーカーが認証トークンをキャッシュする機密データは決してキャッシュしない
サービスワーカーの更新戦略がないskipWaiting() を使用し、ユーザーに更新を促す

本番環境向けチェックリスト

  • アイコンとテーマを含むウェブアプリマニフェスト
  • Workbox の戦略を使用したサービスワーカー
  • オフライン時のフォールバックページ
  • キャッシュの有効期限ポリシー
  • インストールプロンプトの UX
  • Lighthouse の PWA 監査に合格

コメント