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.

    https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app

    「PWAちゃんと対応したいけど今はちょっと・・・」という場合

    src/index.jsを書き換えればOKです。registerServiceWorker()という関数があるので、それを消しましょう。

    すでにビルドしたものを公開済みだという方は、import { unregister } from './registerServiceWorker';して、unregister()を実行することで明示的にとめることができます。

    もしくは(いわゆる力技)

    src/registerServiceWorker.jsregisterValidSW()という関数があります。
    ここにアップデートファイルがあるかどうかの判別式が書かれていますので、ここで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を動かせるようにぜひチャレンジしてみてください。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark