Repository navigation
fix(sw): 安定名アセットの中身を SW のキャッシュ版数に含める (ISSUE-4) - #69
Merged
Merged
Conversation
起票時の前提(HTML だけの変更で版数が上がらない)は、/ が network-first でオンラインのたびにキャッシュを上書きするため実害がほぼ無かった。実際の穴は、フォントが cache-first であること、stale-while-revalidate の裏の更新が waitUntil の外にあること、手書きの precache の一覧から nd.svg と sb.svg が漏れていることだった。 比べた案と、版数に安定名アセットの中身を含める決定(案 C)を ISSUE-4 に、実装の計画を docs/superpowers/plans に置く。
安定名の公開ファイル (アイコン・favicon・manifest・woff2) を差し替えても SW の更新が走るよう、 事前キャッシュ対象を選ぶ isStablePrecache と、内容ハッシュを畳み込む cacheVersion を足す。 CSS・index.html・manifest の参照が漏れなく対象になることをテストで固定する。
public/ の安定名ファイル(アイコン・favicon・manifest・woff2 フォント)を isStablePrecache で選び、パスと内容の SHA-256 を cacheVersion に渡して版数にする。差し替えると版数が変わり、SW の更新と precache のやり直しが走る。 手書きの STABLE_PRECACHE を廃止した。これで nd.svg と sb.svg の取りこぼしもなくなり、OGP 画像や OFL.txt、llms.txt は precache に入らない。読めないファイルがあるときは理由を出してビルドを止める。reject は brandIndexHtmlPlugin と共有する。
public/icons/.DS_Store のような Finder のファイルが前方一致で precache と版数に入り、ローカルのビルドが CI とずれたり、本番で 404 になるパスで SW の install が失敗したりするおそれがあった。 isStablePrecache は末尾の名前が "." で始まるパスを除く。列挙は通常ファイルだけに絞り、/icons/ や /fonts/ 配下のサブディレクトリを readFile して EISDIR になる経路も塞ぐ。
stale-while-revalidate の裏の取得とキャッシュ書き込みが waitUntil に渡っておらず、応答を返した直後に SW が停止されると書き込みが完了せず、2 回目の表示で最新になる保証が崩れていた。handle に waitUntil を通し、キャッシュがあるときだけ裏の Promise を渡す。失敗は従来どおり握りつぶすため、渡す Promise は reject しない。
/fonts/.DS_Store は拡張子の判定だけで落ちるため dotfile 除外の pin にならなかった。/fonts/.hidden.woff2 に替え、dotfile の規則だけが落とす例にする。 版数の並び順のテストは、ハッシュ付きアセットと安定名ファイルを別々に入れ替える。どちらか一方の sort を外しても赤くなる。
- manifest の drift テストで JSON.parse を unknown に受け、型述語で絞る - stale-while-revalidate の waitUntil を catch で書き直す - cacheVersion を関数宣言にし、安定名をオブジェクトのまま path で並べ替える(版数の元の JSON 形が変わる) - sw-strategy / sw / vite.config のコメントを実態に合わせて直す - vite.config の readStable で、ハッシュ計算の失敗を読み取り失敗と誤報しない - 計画書から非公開メモリへの参照を外す
タスクを全部消化したので closed/ へ移し、計画が指す Spec のパスを移動先に合わせる。計画の重複した言い回しも 1 つにまとめた。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
名前を変えずに中身を差し替えるファイル(フォント・アイコン・ロゴ・favicon・manifest)を差し替えてデプロイしたとき、前に来たことがある人には、最初の 1 回だけ古いものが見えてもよいが、2 回目の表示からは必ず新しいものが見えるようにする。
起票時の前提(HTML だけの変更で版数が上がらない)は、
/が network-first でオンラインのたびにキャッシュを上書きするため実害がほぼ無かった。実際の穴は次の 3 つで、ISSUE-4 を書き直して比べた案と決定を残した。/fonts/が cache-first で、同じ名前で差し替えても SW が入れ替わるまで古いままevent.waitUntilの外にあり、SW が止められると書き込まれない/icons/nd.svgと/icons/sb.svgが漏れていた(オフラインでこの 2 つのタグのアイコンが出ない)Closes ISSUE-4
変更
STABLE_PRECACHEをやめ、public/の通常ファイルからisStablePrecache(src/client/sw-strategy.ts)で選ぶ。ドットファイル(Finder の.DS_Storeなど)とディレクトリは除くsrc/client/sw-precache.ts)。どれか 1 つの中身が変わればsw.jsが変わり、SW の入れ替わりで precache 全体が取り直される。/(HTML)は入れないevent.waitUntilに入れた検証
just check: Biome 80 ファイル、vitest 26 ファイル 523 件。just build:(!)0 件cospl-025374e458ee3015。nd.svgに 1 バイト足すとcospl-8b16f4abf5a8d870に変わり、戻すと基準に戻る。OGP 画像だけを変えても、.DS_Storeを置いても基準のまま。ビルドしたsw.jsにnd.svgとsb.svgが 1 件ずつ入る/fonts/の分岐とドットファイルの除外、版数がstableを無視する・並べ替えない(各入力を単独で)・桁数を変える、の各変異で狙ったテストが赤になる。plugin がstableを渡さない変異では、nd.svgを変えても版数が変わらないことをビルドで確かめた。途中で 1 本の死んだ pin(/fonts/.DS_Storeは.woff2の判定で先に偽になっていた)を見つけ、/fonts/.hidden.woff2に置き換えた見送ったこと
addAllが失敗すれば赤くなる