Dive into Hacking with Ham!

create-react-appにより作成されるアプリケーションに同梱されるserviceWorker.jsって何?unregister()って何をしているの?

April 29, 2019

artem-sapegin-176819-unsplash.jpg

はいどうもこんにちは!Dive into Hackingのはむです。2019年のゴールデンウィーク10連休、いかがお過ごしでしょうか?

Reactアプリケーションを作成するためのの定番ボイラープレートcreate-react-app。 先日、v3.0.0にメジャーアップデートされ、まさに安定のツールとなりました。 僕のUdemyのコースReactGraphQLのコースでも利用しているこのcreate-react-appですが、 アプリケーションがあまりにも簡単に作成できてしまうので、つい素通りされがちなんですが、 本記事ではこのcreate-react-appが生成するserviceWorker.jsというファイルが何者なのか、そして、このモジュールを使って実行しているコードが何をやってくれているのかについてご紹介したいなと思います。 尚、本記事で実際に用いたcreate-react-appのバージョンは以下の通りです。

$ create-react-app --version
3.0.0

では、上記バージョンのcreate-react-appを使用していつものようにReactアプリを作成してみます。 アプリケーションの名前は、ちょっと長いですが、what-is-the-role-of-service-workerという名前にします。

$ create-react-app what-is-the-role-of-service-worker

Creating a new React app in /path/to/what-is-the-role-of-service-worker.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts...

yarn add v1.15.2
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
warning "react-scripts > @typescript-eslint/eslint-plugin@1.6.0" has unmet peer dependency "typescript@*".
warning "react-scripts > @typescript-eslint/parser@1.6.0" has unmet peer dependency "typescript@*".
warning "react-scripts > @typescript-eslint/eslint-plugin > @typescript-eslint/typescript-estree@1.6.0" has unmet peer dependency "typescript@*".
warning "react-scripts > @typescript-eslint/eslint-plugin > tsutils@3.10.0" has unmet peer dependency "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev".
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
success Saved 19 new dependencies.
info Direct dependencies
├─ react-dom@16.8.6
├─ react-scripts@3.0.0
└─ react@16.8.6
info All dependencies
├─ @babel/plugin-proposal-class-properties@7.4.0
├─ @babel/plugin-proposal-decorators@7.4.0
├─ @babel/plugin-transform-flow-strip-types@7.4.0
├─ @babel/plugin-transform-runtime@7.4.3
├─ @babel/plugin-transform-typescript@7.4.4
├─ @babel/preset-typescript@7.3.3
├─ babel-plugin-macros@2.5.1
├─ babel-plugin-named-asset-import@0.3.2
├─ babel-preset-react-app@8.0.0
├─ confusing-browser-globals@1.0.7
├─ eslint-config-react-app@4.0.0
├─ fork-ts-checker-webpack-plugin@1.0.1
├─ inquirer@6.2.2
├─ react-app-polyfill@1.0.0
├─ react-dev-utils@9.0.0
├─ react-dom@16.8.6
├─ react-error-overlay@5.1.5
├─ react-scripts@3.0.0
└─ react@16.8.6
✨  Done in 11.97s.

Initialized a git repository.

Success! Created what-is-the-role-of-service-worker at /path/to/what-is-the-role-of-service-worker
Inside that directory, you can run several commands:

  yarn start
    Starts the development server.

  yarn build
    Bundles the app into static files for production.

  yarn test
    Starts the test runner.

  yarn eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd what-is-the-role-of-service-worker
  yarn start

Happy hacking!

では、アプリケーションが作成できたらcdで移動します。

$ cd what-is-the-role-of-service-worker

次に、src/index.jsをエディターで開きます。

$ vim src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

開くと、上記のような内容のJavaScriptのコードとなっているかと思いますが、 今回注目するべき対象は、5行目のserviceWorkerというimport対象のモジュール、そして、そのモジュールを用いて、src/index.jsの最終行でserviceWorker.unregister()を実行している部分になります。 実は、ここでやっていることは非常にシンプルで、serviceWorkerというモジュールにunregister()という関数を実行させています。 英語で解釈すると文字通りの意味になるわけですが、要するに、「解除する」を実行しています。 「え?解除するって何を?」って話なんですが、ここでは、serviceWorkerという別のモジュールでPWA(Progressive Web Application)のキャッシングという機能を有効化、あるいは無効化することができるのですが、create-react-appがデフォルトで出力するコードでは、serviceWorker.unregister()というコードにより、キャッシュを無効化しています。 直前のコメント文をよく見ると、

If you want your app to work offline and load faster, you can change unregister() to register() below. Note this comes with some pitfalls. Learn more about service workers: https://bit.ly/CRA-PWA

という注釈がありますが、前提として、PWAという機能の中に、オフラインという機能があって、ネットワークに接続できないような環境下でもコンテンツをキャッシュすることがうまく利用することでページ遷移を実現できるんですが、これには、ここのserviceWorker.unregister()という部分をunregister()からregister()に変更してね!ってちゃんと書かれています。 本記事を掲載しているブログサイトでもserviceWorkerは健在で(但し、serviceWorker.jsというファイル名ではなく、sw.jsというファイル名になります。)、オフラインでもサイト内のコンテンツであればキャッシュによってページ遷移ができるんです。改めて、このキャッシュをデフォルトで有効にしてくれているGatsbyJSって凄いなぁと実感します。

ちなみに、service workersについては、 https://bit.ly/CRA-PWA を参照あれ!と書かれていますが、このリンクには実はあまり詳細なことは書かれていません。 詳細は、 Google が出している公式のドキュメントService Workerの紹介が良い記事なので一度読んでおくと良いかと思います。

というわけで今回はcreate-react-appが使用するserviceWorkerというモジュール、そしてそのモジュールが有するPWAの一機能であるcacheの有効/無効を制御するコードのご紹介でした。

Dive into Hacking!

はむ


Ham

プログラミングおじさんのHamです。 このサイトではプログラミングに関する様々な記事や動画レクチャー等をお届けしています。 また、Udemy にて、ウェブプログラミング関連のコース(React・Redux/webpack/GraphQLなど)を絶賛配信中です。より体系的に学習したい方にオススメのコースです。