目次
趣味で作成しているPWAで、新バージョンをリリースしても、インストール済みのアプリケーションが更新されない問題が発生しました。
正確には、アプリ起動直後は旧バージョンが立ち上がり、F5リロードを行うと最新版になる。という不可解な挙動をしていました。
今回はこの問題の原因を調べていきます。
ログを確認する
console.logを確認するとbad-precaching-responseというエラーが発生している。
今回の問題に関係あるのだろうか?🤔
一応調べてみる
Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"https://xxxx/_redirects?__WB_REVISION__=xxxxx","status":404}]
Precacheとはなんぞや?
PWAをブラウザにインストールする時(つまりService Workerをインストールする時)に一連のファイルをキャッシュに保存する仕組みの事らしい。
ここが詳しい。
Vue-CLIで生成したPWAはWorkboxというライブラリを使ってService Workerを実装しており、アセットのキャッシュなどをよしなにやってくれている様です。

Precacheを確認する
chromeの開発者ツールのNetworkタブを確認すると、いくつかのファイルはネットワークからではなく、ServiceWorkerから解決している事が分かる。

ApplicationタブのCache StorageでService Workerによってキャッシュされているファイルを確認できる。

Precache-manifestとservice-worker.jsについて
WorkboxをGenerateSWモードでビルドすると、precache-manifestとservice-worker.jsが生成される。

precache-manifestには各リソースのURLとリビジョンが記載されていて、キャッシュのリビジョンと比較して差異があると最新のリソースを取得しにいく。

service-worker.jsでprecache-manifestを読み込んでいるのが分かる。

指定したファイルをprecache-manifestから除外する
改めてエラーログを見直すと、_redirectsというファイルのキャッシュを更新しようとしてエラーになっている事がわかる。
Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"https://xxxx/_redirects?__WB_REVISION__=xxxxx","status":404}]
_redirectsはNetlifyの設定ファイルで、webpack経由でdistフォルダに配置しているのでprecache-manifestに記載されるが、外部からは見えないので404になってしまっている。
vue.config.jsのworkboxOptionsで_redirectsを除外する。
module.exports = {
pwa: {
workboxPluginMode: 'GenerateSW',
workboxOptions: {
exclude: /_redirects/
}
}
}
結果
bad-precaching-responseエラーが発生しなくなって、その他のファイルのキャッシュも更新されました!🙆precache-manifestのファイルが1つでも404になると全てのキャッシュが更新されなくなるのかもしれない。
Webエンジニアをやっています
UX/UIデザインからプログラミング、DB設計、SEO、インフラ構築など幅広く対応してます
PHP/PHPUnit/Laravel/Vue/Nuxt/Docker/Terraform
ご連絡はTwitterのDMまで。
