create-react-appで作ったReact SPAにWorkbox-CLIでService Workerをねじ込む
create-react-appにService Workerついてるんですよね。一応。 ただしランタイムキャッシュの設定とかしたいなぁってなった時に、npm run ejectしろってなるのであまり使いたくない感があり […]
目次
create-react-appにService Workerついてるんですよね。一応。
ただしランタイムキャッシュの設定とかしたいなぁってなった時に、npm run eject
しろってなるのであまり使いたくない感がありまして。
「だったらWorkbox-cliで手動で入れるか」という試みです。
$ workbox --version
3.0.0
対話形式でセットアップ
対話形式でセットアップします。ここは基本的にデフォルトでOKです。root of your web app
はbuild
になりますので、sw.jsの配置場所などはそこにしておきましょう。あとはworkbox-config.js
は.gitignoreしないように気をつけてください。sw.jsはこのファイルから生成するものなので省略しちゃってOKです。
$ workbox wizard
? What is the root of your web app (i.e. which directory do you deploy)? build/
? Which file types would you like to precache? json, png, ico, html, js, xml, css
? Where would you like your service worker file to be saved? build/sw.js
? Where would you like to save these configuration options? workbox-config.js
To build your service worker, run
workbox generateSW workbox-config.js
as part of a build process. See https://goo.gl/fdTQBf for details.
You can further customize your service worker by making changes to workbox-config.js. See https://goo.gl/gVo87N for details.
変更後はこうなります。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
workbox-config.js
$ cat workbox-config.js
module.exports = {
"globDirectory": "build/",
"globPatterns": [
"**/*.{json,png,ico,html,js,xml,css}"
],
"swDest": "build/sw.js"
};
Service Workerの設定を書く
先ほど作ったworkbox-config.js
に設定を書いていきます。runtimeCaching
に外部から持ってくるもののキャッシュ設定を書いていきましょう。あと、navigateFallback
を設定し忘れると、react-routerなどでルーティングさせてる場合にオフラインで事故ります。
module.exports = {
"globDirectory": "build/",
"globPatterns": [
"**/*.{json,png,ico,html,js,xml,css}"
],
"swDest": "build/sw.js",
"navigateFallback": '/index.html',
"runtimeCaching": [
{
urlPattern: /^https:\/\/cdnjs\.cloudflare\.com\/ajax\/libs\/slick-carousel\/1\.6\.0\/slick\.min\.css/,
handler: 'cacheFirst',
options: {
cacheName: 'slick-min',
expiration: {
maxEntries: 80,
maxAgeSeconds: 60 * 60 * 24
}
}
},
...
最後に変換して終わりです。
$ workbox generateSW workbox-config.js
$ cat build/sw.js
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.0.0/workbox-sw.js");
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [
{
"url": "asset-manifest.json",
"revision": "083db5510bccc5483174e3dff8b7ac6d"
},
{
"url": "assets/favicon/favicon-16x16.png",
"revision": "6e1b9c138332350d1bc8c4df3048d339"
},
{
"url": "assets/favicon/favicon-32x32.png",
"revision": "458476695d9f85b8a006de9dc0266ed8"
},
{
"url": "assets/favicon/favicon.ico",
"revision": "6679c88c1fc7f22dc32f0b2558b3653b"
},
{
"url": "assets/favicon/manifest.json",
"revision": "f16d818905bcd39ebaab1f7dd1a37eed"
},
{
"url": "favicon.ico",
"revision": "c92b85a5b907c70211f4ec25e29a8c4a"
},
{
"url": "index.html",
"revision": "099c9063f8e1839296cba3b204b1c533"
},
{
"url": "manifest.json",
"revision": "730915ec2725cf6721080a6516b23f15"
},
{
"url": "service-worker.js",
"revision": "ed22c798cbc34f7c29d6effda7ddc65e"
},
{
"url": "sitemap.xml",
"revision": "281e5a319b915b53a51f8372a2c0db9d"
},
{
"url": "static/css/main.4de8d704.css",
"revision": "1af8ae00d038c10b786769159200fc48"
},
{
"url": "static/js/main.f8977b6b.js",
"revision": "9bfb5bf61040ab2d9852303cef585b24"
}
].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
workbox.routing.registerRoute(/^https:\/\/cdnjs\.cloudflare\.com\/ajax\/libs\/slick-carousel\/1\.6\.0\/slick\.min\.css/, workbox.strategies.cacheFirst({ cacheName: "bootstrap", plugins: [new workbox.expiration.Plugin({"maxEntries":80,"maxAgeSeconds":86400})] }), 'GET');
...
React SPAで読み込ませる
このままindex.htmlに書いてもいいのですが、create-react-app
が用意しているregister関数がそこそこ優秀(localhostやdevビルドを除外・解除用ヘルパーもある)なので、そっちを使います。
src/registerServiceWorker.js
に設定が書かれているので、service-worker.js
というファイル名の記述をWorkbox-cliで作ったものに書き換えておきましょう。
ビルドコマンドに追加する
最後にCDパイプラインにのせても動くようにしておきましょう。
$ npm i -d workbox-cli
$ vim package.json
...
"scripts": {
"build": "react-scripts build && ./node_modules/.bin/workbox generateSW workbox-config.js ",
...
workbox-cliをグローバルに入れてもいいのですが、それだとコマンド増えるのでdevDependenciesに入れてそっちでやっちゃいます。
あとreact-scripts build
より先にworkbox generateSW
を実行してしまうと、ビルド時に生成されるJSファイル名にハッシュが入っている関係上やはり事故ります。
取り急ぎ以上です。