|
| 1 | +# PWA 化 + MapView オンライン限定表示 |
| 2 | + |
| 3 | +## Context |
| 4 | +このアプリ(レシート撮影 + GPS 記録)をオフラインでも使えるよう PWA 化する。 |
| 5 | +ただし地図タイル(OpenStreetMap)はオフラインで取得不可のため、MapLibre GL JS はオンライン時のみ動的 import して表示する。 |
| 6 | + |
| 7 | +## 変更対象ファイル |
| 8 | + |
| 9 | +| ファイル | 変更内容 | |
| 10 | +|---------|---------| |
| 11 | +| `package.json` | `vite-plugin-pwa` を devDependencies に追加 | |
| 12 | +| `vite.config.ts` | VitePWA プラグイン設定追加(manifest, service worker) | |
| 13 | +| `index.html` | `theme-color` meta タグ追加 | |
| 14 | +| `src/lib/MapView.svelte` | 動的 import 方式に変更 | |
| 15 | +| `src/lib/ListWrapper.svelte` | オンライン状態監視 + MapView の条件付き表示 | |
| 16 | +| `public/` | PWA アイコン画像追加(192x192, 512x512) | |
| 17 | + |
| 18 | +## 実装ステップ |
| 19 | + |
| 20 | +### 1. `vite-plugin-pwa` のインストール |
| 21 | +``` |
| 22 | +pnpm add -D vite-plugin-pwa |
| 23 | +``` |
| 24 | + |
| 25 | +### 2. `vite.config.ts` に PWA プラグイン追加 |
| 26 | +- `VitePWA` プラグインを追加 |
| 27 | +- manifest 設定: name, short_name, theme_color, icons 等 |
| 28 | +- `registerType: 'autoUpdate'` で自動更新 |
| 29 | +- Service Worker のキャッシュ戦略を設定(`generateSW` モード) |
| 30 | +- MapLibre 関連の JS チャンクを precache 対象から除外する(`workbox.navigateFallbackDenylist` や `globPatterns` で制御) |
| 31 | + |
| 32 | +### 3. `index.html` に meta タグ追加 |
| 33 | +- `<meta name="theme-color">` を追加 |
| 34 | + |
| 35 | +### 4. `src/lib/MapView.svelte` を動的 import 対応に変更 |
| 36 | +- `import maplibregl from 'maplibre-gl'` を静的 import から削除 |
| 37 | +- `onMount` 内で `const maplibregl = (await import('maplibre-gl')).default` を使用 |
| 38 | +- CSS も動的にロード: `await import('maplibre-gl/dist/maplibre-gl.css')` |
| 39 | +- これにより MapLibre がメインバンドルから分離され、別チャンクになる |
| 40 | + |
| 41 | +### 5. `src/lib/ListWrapper.svelte` にオンライン状態監視を追加 |
| 42 | +- `navigator.onLine` で初期状態を取得し `$state` で管理 |
| 43 | +- `onMount` で `online`/`offline` イベントリスナーを登録(`onDestroy` で解除) |
| 44 | +- オンライン時: `<MapView>` を表示 |
| 45 | +- オフライン時: 「オフラインのため地図を表示できません」等の代替メッセージを表示 |
| 46 | + |
| 47 | +### 6. PWA アイコンの準備 |
| 48 | +- シンプルなプレースホルダーアイコン(SVG ベース)を `public/` に配置 |
| 49 | +- 192x192 と 512x512 の 2 サイズ |
| 50 | + |
| 51 | +## 検証方法 |
| 52 | +1. `pnpm build && pnpm preview` でビルド後プレビュー |
| 53 | +2. Chrome DevTools > Application タブで manifest と Service Worker が登録されていることを確認 |
| 54 | +3. DevTools > Network タブで「Offline」にチェック → アプリが動作し、地図部分のみ代替表示になることを確認 |
| 55 | +4. `pnpm check` で TypeScript エラーがないことを確認 |
0 commit comments