TECHNICAL ARTICLE / PWA & PERFORMANCE
BuildレスPure Static Webアプリにおける Service Worker キャッシュと相対パス設計
Vite や Webpack 等のバンドラーを使用せず、標準の HTML5 / CSS3 / Native ES Modules のみで構成された Pure Static アプリ(BorderLens 等)において、GitHub Pages サブパスとルートドメイン環境で完全なオフラインキャッシュと自動更新を両立させた開発ノート。
1. 背景と課題 (Problem)
渡航制限・危険情報・ビザ要件を可視化する静的アプリ BorderLens の開発において、開発の軽量化と長期的なメンテナンス性を維持するため、TypeScript やビルドステップを一切挟まない Pure Static HTML/ES Modules 構成 を採用しました。
しかし、Service Worker(PWA オフライン対応)を導入する際、以下の課題に突き当たりました。
- デプロイ先URLの絶対パス依存: GitHub Pages サブパス(
/borderlens/)と Cloudflare Pages / カスタムドメイン(/)で静的アセットの fetch パスがズレる。 - キャッシュ更新漏れによる古い状態の永続化: ビルドステップによるハッシュ付きファイル名生成(例:
app.a1b2c3.js)が存在しないため、ブラウザキャッシュが残り続ける。
2. 解決アプローチと相対パスの統一 (Architecture & Implementation)
① 100% 相対パス (./) の徹底
Service Worker のアセット定義リスト(キャッシュマニフェスト)および ES Modules の `import` 文において、先頭の `/` を排除し、すべて ./ から始まる相対パスで静的アセット(全 45 ファイル)を指定しました。
// sw.js 内のキャッシュ対象リスト定義
const CACHE_NAME = 'borderlens-v1.0.4';
const ASSETS_TO_CACHE = [
'./',
'./index.html',
'./404.html',
'./styles.css',
'./src/pages/MainApp.js',
'./src/services/dataStore.js',
'./src/data/countries.json',
'./src/data/official-portals.json',
'./src/data/visa-rules.json'
];
// install イベントでのアセット一括追加
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(ASSETS_TO_CACHE);
})
);
self.skipWaiting();
});
② Python による Pre-flight 自動検証スクリプト
手動でのファイル追加忘れやパス間違いを防止するため、デプロイ前に python3 scripts/verify_build.py を実行する事前検証パイプラインを構築しました。全 JSON の構文チェック、ES Modules の依存関係テスト、および sw.js にリストされた全アセットの実ファイル存在チェックを自動実行します。
# verify_build.py からの抜粋(アセット自動整合性アサート)
for asset_path in sw_cache_assets:
local_path = asset_path.lstrip('./')
if not os.path.exists(local_path):
print(f"❌ SW Cache Asset Missing: {asset_path}")
sys.exit(1)
print("✅ ALL SERVICE WORKER ASSETS PASSED INTEGRITY CHECK!")
3. 得られた成果と結果 (Results)
- マルチ環境対応: 同一のリポジトリコードで、
https://borderlens.com/でもhttps://koshijpn.github.io/borderlens/でも修正なしでオフライン起動が可能になりました。 - ゼロ障害デプロイ: Pre-flight 検証スクリプトにより、45 ファイル中 1 つでも欠落していた場合は CI/CD やローカルコミットで即時にブロックされる安全性を確保しました。