create-react-appで作ったアプリの更新がうまくいかない場合は、Service Workerが原因かもしれない
原因という言い方をするとSerivce Workerが悪いみたいに聞こえるかもですが、悪いのは対応してなかったユーザー側だと思います。 React SPAのキャッシュがやたらと効く アプデしたはずが、ユーザーからのバグ報 […]
目次
原因という言い方をするとSerivce Workerが悪いみたいに聞こえるかもですが、悪いのは対応してなかったユーザー側だと思います。
React SPAのキャッシュがやたらと効く
アプデしたはずが、ユーザーからのバグ報告などを見ると、前のバージョンのソースを参照しているとしか思えないというケースがちょいちょいありました。
これ、実はReadme.mdを読めば一発でわかる現象で、npm run build
したものはPWAにデフォルトで対応しているようになっているからです。
By default, the production build is a fully functional, offline-first Progressive Web App.
「PWAちゃんと対応したいけど今はちょっと・・・」という場合
src/index.js
を書き換えればOKです。registerServiceWorker()
という関数があるので、それを消しましょう。
すでにビルドしたものを公開済みだという方は、import { unregister } from './registerServiceWorker';
して、unregister()
を実行することで明示的にとめることができます。
もしくは(いわゆる力技)
src/registerServiceWorker.js
にregisterValidSW()
という関数があります。
ここにアップデートファイルがあるかどうかの判別式が書かれていますので、ここでwindow.location.reload(true)
して強制的にスーパーリロードさせるという方法もありといえばありかなと思います。
function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// ここで強制的にスーパーリロードさせる
window.location.reload(true);
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
どう考えても力技なのでプロダクションに導入はしてませんが、アイディアとしては1つあるかなと思いここに記録します。
とはいえ
オフラインでも使える方がユーザーとしてはありがたいですし、これを機にオフラインでも自分のSPAを動かせるようにぜひチャレンジしてみてください。