Workbox webpack Plugins の GenerateSW 仕様

最近 webpack を使ってWebアプリを作る仕事が多く、加えてPWAと話もちらほらとなってきたので情報を探していたら`Workbox webpack Plugins`というものに辿り着いた。（途中経過はかなり端折っている）
どうやって使うものなのか詳しく調べようと思ったが日本語の説明サイトでは全体像を説明しているところが見つからなかったため自分で調べることにした。

# Workbox って？
[公式サイト](https://developers.google.com/web/tools/workbox/)
Webアプリのオフライン処理をサポートするJavaScriptライブラリらしい。

`PWA`を構成する機能のひとつが`ServiceWorker`。`ServiceWorker`は（ざっくり言うと）ブラウザのAjax通信をインターセプトしてキャッシュ
を返すか実体を返すかなどを分岐できる機能がある。WorkboxはそのServiceWorkerの実装を簡易化してくれるもの、と認識している。

ちなみに公式サイトには頻繁に`precache`という単語（用語？）が出てくる。`precache`はServiceWorkerが機能するタイミング(install)でユーザーアクセスに関わらず事前にキャッシュするものらしい。そうじゃないキャッシュはAPI呼び出し時(fetch)の応答などになり動的キャッシュになる。
以降はそれぞれ`プレキャッシュ`と`ランタイムキャッシュ`と呼ぶことにする。

`Workbox webpack Plugins`は`GenerateSW`と`InjectManifest`の2つの機能を提供している。まずは`GenerateSW`にどんな機能があるのかを調査する。

英訳のセンスが高くないためこの先記述する内容は最終的に公式サイトで確認することをオススメする。英訳に誤まりがある場合はご指摘大歓迎です。

以降の記載はすべて[Workbox webpack Plugins サイト](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#configuration)をベース（というかほぼそのもの）にしている。

# GenerateSW
`GenerateSW`は`webpack asset`とのパイプを持つServiceWorkerファイルを生成する。`webpack`でビルドする時に静的ファイルの場所は認識できるのでそれらをプレキャッシュ対象として認識してくれるということだと思う。

## GenerateSW を使うケース、使わないケース
- 使うケース
    - プレキャッシュ機能を使いたい（言うまでもないけど）
    - そんなに複雑な処理を必要としない
- 使わないケース
    - `ServiceWorker`以外の機能（`Web Push`など）も使いたい
    - （生成した`ServiceWorker`ファイルに）独自のロジックを入れたい

## 指定可能なオプション

**webpackコンパイル時に適用されるもの**

| キー       | 型     |   必須 | 未指定時のデフォルト | 説明 |
|:----------|:-------|:-----:|:----------------|:-----|
| swDest | string    || service-worker.js | ビルドで生成されるServiceWorkerファイルのパスとファイル名を<br>webpackのoutput設定からの相対パスで指定する。 |
| importWorkboxFrom | enum: string | | cdn | Workboxのランタイムライブラリをどこから調達するかの設定<br>● cdn: 可用性ある'Google Cloud Storage'からダウンロードして使う。<br>● local: ローカルコピーを使う。このオプションを選択する場合はローカルにライブラリを用意しておく必要がある。<br>● disabled: importScriptsオプションを使って`workbox-sw.js`へのパスを自分で通せ。<br>※Workboxランタイムライブラリを含む`webpackモジュール`のパスを指定することも許容するらしい。（ただしそれはこのオプションではなく`importScripts`で、ということだと思われる...） |
| chunks | string[] || [] | プレキャッシュ対象のモジュール名(本文では`chank name`)を明示的にホワイトリスト方式で指定する。デフォルト設定のままだとなんでもかんでもプレキャッシュするということだと。 |
| excludeChunks |  string[] | | [] | プレキャッシュ対象にしないモジュール名(本文では`chank name`)を明示的にブラックリスト方式で指定する。デフォルトだと...以下同文。 |
| include     | string[], RegExp[] |  | [] | プレキャッシュ対象のモジュールをファイル名ベース（正規表現もOK）で指定する。（多分何も指定しない場合だと思うけど）`webpack`のtestオプションを使用する。 |
| exclude          | string[], RegExp[] | | [/\\.map\$/, /^manifest.*\\.js\$/] | プレキャッシュ対象にしないモジュールをファイル名ベース（正規表現もOK）で指定する。 |
| importsDirectory | string | | | webpackコンパイル時にWorkboxが生成するassetsの出力場所を（webpackのoutput.pathのサブディレクトリとして）指定する。<br>※ただしServiceWorkerファイルについてはこのオプション指定に左右されない。 |
| precacheManifestFilename | string | | precache-manifest.[manifestHash].js | Workboxが生成するマニフェストファイル（プレキャッシュするのに必要となるURLなどを含むものらしい）のファイル名を変えたい時に指定する。ただし'[manifestHash]'は必ずファイル名に含める必要がある。<br>※このオプションで指定できるのはファイル名だけ、出力パスを変えたい場合は`importsDirectory`を使用する。 |

**webpackコンパイルに影響しないもの**

| キー       | 型     |   必須 | 未指定時のデフォルト | 説明 |
|:----------|:-------|:-----:|:----------------|:-----|
| importWorkboxFrom   | string    || cdn | （なぜここにある...？詳細は↑を参照） |
| skipWaiting   | boolean    || false | ServiceWorkerの更新時にwait状態を無視して制御を乗っ取るかどうか。（skipWaitingの説明は別途するとしておそらく false のままでいいんじゃないか...と） |
| clientsClaim   | boolean    || false | ServiceWorkerの新規install後にすぐに（ページのリロードとかなしで）制御できるようにするかどうか。（ServiceWorker無しでは機能しないアプリとかじゃない限り false のままでいいんじゃないか...と）  |
| runtimeCaching   | object[]    || [] | 動的なAPI応答などをランタイムキャッシュするための指定。'urlPattern'、'handler'、'options'をキーに持つオブジェクトでキャッシュ方法を指定する。（これについては元サイトの実装例を見るのが一番分かり易い） |
| navigateFallback   | string    || undefined | なんらかの理由でキャッシュ対象にならないリソースをキャッシュするためのルート（NavigationRoute）を指定する。主にはSPAで使い回されるファイルなどをキャッシュ対象にするための設定らしい。 |
| navigateFallbackBlacklist   | RegExp[]    || [] | 'navigateFallback'設定が適用する範囲を制限するためのブラックリスト。<br>ブラックリストとホワイトリストが両方指定されている時はブラックリストが優先される。 |
| navigateFallbackWhitelist   | RegExp[]    || [] | 'navigateFallback'設定が適用する範囲を制限するためのホワイトリスト。<br>ブラックリストとホワイトリストが両方指定されている時はブラックリストが優先される。 |
| importScripts   | string[]    | ○ | - | ServiceWorkerから importScripts() を使ってインポートする必要があるJavaScriptファイルを指定する。また、インポートするJavaScriptファイルで 'self.__precacheManifest' にプレキャッシュしたいファイルのURLを指定するとプレキャッシュ対象になる。この設定でpushイベントを処理する追加コードなどをServiceWorkerに含めることができる。（ん？できるのそれ。。そして必須なのこのオプション。。） |
| ignoreURLParametersMatching   | RegExp[]    || [/^utm_/] | キャッシュ検索のときに無視するパラメータを指定する。デフォルトだとキャンペーンパラメータはすべて無視するようになっている。 |
| directoryIndex   | string    || index.html | ウェルカムページをプレキャッシュに含めるための設定。末尾'/'でリクエストされて応答するファイル名を指定する。 |
| cacheId   | string    || null | Workboxがキャッシュ名に付けるID。主にローカルで開発時に使うもので同じlocalドメインで複数のサイトをホストしているケースで役に立つとのこと。 |
| offlineGoogleAnalytics   | boolean    || false | 'Offline Google Analytics'のON/OFFスイッチ。trueに設定すると Background Sync によるGoogleAnalyticsをうまいことやってくれる？らしい。 |
| cleanupOutdatedCaches   | boolean    || false | ~~時代遅れ~~旧バージョンのキャッシュを削除してくれる設定。~~（だとしたらなぜデフォルトが false ？）~~旧バージョンと齟齬がある場合だけということなのでデフォルトは false ですね。 |
| globDirectory   | string    || undefined | 'globPatterns'設定が使用するベースディレクトリを指定する。これを指定する場合は'globPatterns'指定も必須。 |
| globFollow   | boolean    || true | プレキャッシュのマニフェスト生成時に symlinks を追従するかどうかを指定する。 |
| globIgnores   | string[]    || ['node_modules/**/*'] | プレキャッシュのマニフェスト生成時に除外するファイルをglob指定する。 |
| globPatterns   | string[]    || [] | プレキャッシュのマニフェスト生成時に対象とするファイルをglob指定する。ただし workbox-webpack-plugin の場合は webpack の静的ファイルは自動で対象になるためほとんどの場合指定する必要はない。 |
| globStrict   | boolean    || true | プレキャッシュのマニフェスト生成時にglob指定のディレクトリの読み取りエラーが発生した場合にビルドをエラー終了させるかどうかを指定する。 |
| templatedURLs   | object    || null | プレキャッシュするファイル中で "呼び出される複数のファイルの内容" または "記述される特定の文字列" を、プレキャッシュするファイルの一意性を示すバージョンとして使用する場合に指定する。（英訳微妙？）<br>objectにはstring[]またはstringを指定できる。 |
| maximumFileSizeToCacheInBytes   | Number    || 2097152 | プレキャッシュする（「ひとつの」だと思うが本文には特に記述なし）ファイルの最大サイズを指定する。不注意な指定で巨大なファイルをキャッシュしてしまう動作を防止する。 |
| dontCacheBustURLsMatching   | RegExp    || null | プレキャッシュ時の一意性を判断する時のフィルターのようなものとして指定する。例えば静的ファイルに必ずハッシュ値を付与しているような場合に同じファイルを複数キャッシュしてしまわないために使用する。（おそらくここで指定した正規表現部分を削った名前で比較するという意味じゃなろうか、違うかな...？） |
| modifyURLPrefix   | object    || null | プレキャッシュのマニフェストのエントリーに前置詞を付与（または削除）する。静的ファイル置き場がローカルとデプロイ時で異なる場合などに使用する。より柔軟な対応が必要なら 'manifestTransforms' オプションを使う。<br>objectにはstringのみ指定可能。 |
| manifestTransforms   | [ManifestTransform](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.ManifestTransform)[]    || null | プレキャッシュのマニフェストのエントリーに対して柔軟なカスタマイズを行う。静的ファイルのある特定のファイルだけパスを変えたり、などなど。'modifyURLPrefix' や 'dontCacheBustURLsMatching' オプションを併用している場合はそれらが先に適用される。 |

やや見辛いテーブルになってしまったので今後修正していきます。