Workboxを使うと何ができるのか？Workboxの各packageのまとめ

## Workboxとは

Workboxとは、Service Workerを簡単に使えるように、各種APIを抽象化したモジュールを集めたものです。

> Workbox is a set of modules that simplify common service worker routing and caching.

Service Workerを使うには、ネットワークリクエスト、キャッシュ戦略、キャッシュ管理、プリキャッシュなど必要な知識が多く、それらを抽象化することで取り組みやすく、かつ柔軟にカスタマイズもできるようになっています。

https://developer.chrome.com/docs/workbox/what-is-workbox/

Workboxを手軽に使う方法としては、`generateSW` や `injectManifest` を使う方法があります。

https://developer.chrome.com/docs/workbox/the-ways-of-workbox/

またその他にもWorkboxの各モジュールを使用する方法があり、その場合にどういうときにどれを使えばいいのかを整理したくなったため、調べてまとめてみました。

## Workbox Modules

https://developer.chrome.com/docs/workbox/modules/

上記ページには、Service Worker Packagesとして以下のようなパッケージが挙げられています。
それぞれの機能を調べながら、Workboxでできることをまとめます。

- [workbox-background-sync](https://developer.chrome.com/docs/workbox/modules/workbox-background-sync/)
- [workbox-broadcast-update](https://developer.chrome.com/docs/workbox/modules/workbox-broadcast-update/)
- [workbox-cacheable-response](https://developer.chrome.com/docs/workbox/modules/workbox-cacheable-response/)
- [workbox-core](https://developer.chrome.com/docs/workbox/modules/workbox-core/)
- [workbox-expiration](https://developer.chrome.com/docs/workbox/modules/workbox-expiration/)
- [workbox-google-analytics](https://developer.chrome.com/docs/workbox/modules/workbox-google-analytics/)
- [workbox-navigation-preload](https://developer.chrome.com/docs/workbox/modules/workbox-navigation-preload/)
- [workbox-precaching](https://developer.chrome.com/docs/workbox/modules/workbox-precaching/)
- [workbox-range-requests](https://developer.chrome.com/docs/workbox/modules/workbox-range-request/)
- [workbox-recipes](https://developer.chrome.com/docs/workbox/modules/workbox-recipes/)
- [workbox-routing](https://developer.chrome.com/docs/workbox/modules/workbox-routing/)
- [workbox-strategies](https://developer.chrome.com/docs/workbox/modules/workbox-strategies/)

:::note
2022年6月現在、Workboxの最新バージョンはv6.5.2です
:::

ここからはworkboxのドキュメントを引用しながらまとめていきます。

https://developer.chrome.com/docs/workbox/modules/

### [workbox-routing](https://developer.chrome.com/docs/workbox/modules/workbox-routing/)

ネットワークリクエスト時に、Service Workerが間に入って処理をすることができますが、このルーティング設定ができます。

ルーティング条件とhandlerを設定することで、特定のルーティングの時にService Workerがキャッシュをブラウザに返すなどといった設定や、エラー発生時のハンドリングなどを設定できます。

```js
registerRoute(new RegExp('/styles/.*\\.css'), handlerCb);
```

### [workbox-strategies](https://developer.chrome.com/docs/workbox/modules/workbox-strategies/)

キャッシュ戦略を設定できます。

Cache only / Network only / Cache first / Network first / Stale-while-revalidate などの詳細はこちらをご覧ください。

https://developer.chrome.com/docs/workbox/caching-strategies-overview/

workbox-routingと合わせて使うことで、ルーティングによってキャッシュ戦略を変更できます。

```js
registerRoute(
  ({url}) => url.pathname.startsWith('/social-timeline/'),
  new NetworkFirst()
);
```

また、カスタムストラテジーとして、`Strategy`クラスを継承した独自の戦略を定義することもできます。

### [workbox-precaching](https://developer.chrome.com/docs/workbox/modules/workbox-precaching/)

プリキャッシュの設定ができます。
Service Workerには precaching と runtime caching という2つの概念があり、このうちService Workerインストール時に事前キャッシュする、 precache を指しています。
それぞれの説明はこちらをご覧ください。

https://developer.chrome.com/docs/workbox/service-worker-overview/#precaching-and-runtime-caching

Service Workerのinstallイベントの最中に、アセットの事前ダウンロードとキャッシュを行い、その際に古くなったキャッシュの削除なども行えます。
事前にダウンロードしておくことで、次回以降のリクエスト発生時に、キャッシュファーストで応答ができます。

```js
precacheAndRoute([
  {url: '/index.html', revision: '383676'},
  {url: '/styles/app.0c9a31.css', revision: null},
  {url: '/scripts/app.0d5770.js', revision: null},
  // ... other entries ...
]);
```

### [workbox-expiration](https://developer.chrome.com/docs/workbox/modules/workbox-expiration/)

キャッシュの期間や保存する数の管理ができます。

workbox-strategiesと組み合わせて、各キャッシュ戦略ごとの設定ができます。

```js
registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    cacheName: 'image-cache',
    plugins: [
      new ExpirationPlugin({
        maxEntries: 20,
        maxAgeSeconds: 24 * 60 * 60,
      }),
    ],
  })
);
```

### [workbox-core](https://developer.chrome.com/docs/workbox/modules/workbox-core/)

各モジュールが依存するロジックが含まれています。
デバッグや型定義の使用などで使います。

```js
console.log(cacheNames.precache);
console.log(cacheNames.runtime);
console.log(cacheNames.googleAnalytics);
```

また、キャッシュ名の変更もできます。

```js
setCacheNameDetails({
  prefix: 'my-app',
  suffix: 'v1',
  precache: 'install-time',
  runtime: 'run-time',
  googleAnalytics: 'ga',
});

// Will print 'my-app-install-time-v1'
console.log(cacheNames.precache);
```

### [workbox-background-sync](https://developer.chrome.com/docs/workbox/modules/workbox-background-sync/)

バックグラウンド同期を使って、オフラインなどでネットワークリクエストが失敗した場合、接続ができたタイミングでリクエストを再送信できます。

キューを作成し、一定時間以内のものをバックグラウンド同期するといったものが設定できます。

```js
const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
  maxRetentionTime: 24 * 60, // Retry for max of 24 Hours (specified in minutes)
});

registerRoute(
  /\/api\/.*\/*.json/,
  new NetworkOnly({
    plugins: [bgSyncPlugin],
  }),
  'POST'
);
```

### [workbox-broadcast-update](https://developer.chrome.com/docs/workbox/modules/workbox-broadcast-update/)

キャッシュの更新が検知されたときに、通知します。
一般的に、StaleWhileRevalidateとともに使われます。

```js
registerRoute(
  ({url}) => url.pathname.startsWith('/api/'),
  new StaleWhileRevalidate({
    plugins: [new BroadcastUpdatePlugin()],
  })
);
```

### [workbox-cacheable-response](https://developer.chrome.com/docs/workbox/modules/workbox-cacheable-response/)

キャッシュをするかどうかを、レスポンスのステータスコードか、レスポンスヘッダーに基づきルールを設定できます。

```js
registerRoute(
  ({url}) => url.pathname.startsWith('/path/to/api/'),
  new StaleWhileRevalidate({
    cacheName: 'api-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [200, 404],
        headers: {
          'X-Is-Cacheable': 'true',
        },
      }),
    ],
  })
);
```

### [workbox-google-analytics](https://developer.chrome.com/docs/workbox/modules/workbox-google-analytics/)

オフライン時のユーザーデータをGoogle Analyticsに送信するために、一時的にIndexedDBに保存し、ネットワーク接続がされた時に再試行できます。

```js
import * as googleAnalytics from 'workbox-google-analytics';

googleAnalytics.initialize();
```

カスタムディメンションを使って、オンラインとオフラインを分けて分析することもできます。

### [workbox-navigation-preload](https://developer.chrome.com/docs/workbox/modules/workbox-navigation-preload/)

navigation preloadを使うことで、Service Workerがアクティブになる前にリクエストをすることができます。

https://developer.chrome.com/blog/navigation-preload/

Service Workerの起動に時間がかかると、その間リクエストが遅延してしまいますが、これを防ぐことができます。

```js
navigationPreload.enable();
```

### [workbox-range-requests](https://developer.chrome.com/docs/workbox/modules/workbox-range-request/)

ビデオファイルの再生などで、キャッシュされたファイルの一部のみを返したい時に使えます。

```js
registerRoute(
  ({url}) => url.pathname.endsWith('.mp4'),
  new CacheFirst({
    plugins: [
      new RangeRequestsPlugin(),
    ],
  });
);
```

### [workbox-recipes](https://developer.chrome.com/docs/workbox/modules/workbox-recipes/)

よく使われるパターンをレシピとして使うことができます。

<dl>
<dt>offlineFallback</dt><dd>
オフラインで、かつキャッシュが存在しない場合にフォールバックとして表示する設定
</dd><dt>warmStrategyCache</dt><dd>
Service Workerのinstallフェーズに特定のキャッシュ戦略でキャッシュのウォームアップ
</dd><dt>pageCache</dt><dd>
ページキャッシュ
</dd><dt>staticResourceCache</dt><dd>
CSS, JavaScript, Web WorkerのリクエストをStaleWhileRevalidateでのキャッシュ
</dd><dt>imageCache</dt><dd>
imageのキャッシュ
</dd><dt>googleFontsCache</dt><dd>

GoogleFontsの`@font-face`定義、フォントファイルのキャッシュ
</dd></dl>

## 参考

https://developer.chrome.com/docs/workbox/