Vue.jsでPWAアプリを作る

# 1. PWAとは？
PWA(Progressive Web Apps)はGoogle Chromeエンジニア Alex Russell氏が2015年に考案した概念として知られています。特徴としてネイティブアプリのようなユーザー体験をWEBで提供するのが目的です。

## PWAの特徴
- **FAST** : パフォーマンスの良い、軽決な動作
- **Integrated** : OSと統合されたユーザー体験
- **Engaging** : アプリのような体験を提供
- **Reliable** : オフラインでも動作する便利性

## PWAを実現するAPI
PWAを実現するために中心となる機能を提供するのが「**Service Worker**」です。
###**Service Worker**
Service Workerは「バックグラウンドで動作するプログラミング可能なネットワークプロキシ」のことです。Service Workerを利用するとWebページのオフライン対応をはじめ、キャッシュ、バックグラウンド同期、Push通知の機能を提供します。ただし条件としてlocalhost接続以外はHTTPSの使用が必須となっています。

####**キャッシュ**
Service WorkerはWebページからリクエストのリソースがキャッシュ内に存在すると、そのキャッシュされたリソースを返します。その時通信しないので、高速で動作し、通信コストが発生しません。

####**バックグラウンド同期**
オフライン中にユーザーが行った動作をキャッシュし、オンライン時にその内容を同期することができます。例えばチャットサービスを使っていて電波が悪くなる時がありますが、オフラインでもメッセージを送信しておくと電波環境が良くなりオンラインになったタイミングで同期することができます。

####**Push通知**
Service WorkerはWebアプリでもPush通知を送ることができます。Webページがアクティブでなくても、サーバーからのPushを受け取り、ユーザーに通知を送ることができます。

#2. PWAとVue.jsの環境構築
##vue-pwa-boilerplate
[vue-pwa-boilerplate](https://github.com/vuejs-templates/pwa)を使い環境構築していきます。
vue-pwa-boilerplateはVue.jsでPWAで開発するためのひな形であり、必要な環境が揃っています。
[vue-pwa-boileraplate](https://github.com/vuejs-templates/pwa)を使うためには「vue-cli」が必要なので、インストールしましょう。

```
$ npm install -g vue-cli
$ vue init pwa my-project
$ cd my-project
$ npm install
$ npm run dev
```

実行すると自動でブラウザが起動し`http://localhost:8080/`を呼び出します。最初はこんな画面です。

<img width="428" alt="スクリーンショット 2018-09-27 23.30.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/269837/c26d5a95-f353-405d-21d9-bf8e641089f8.png">


PWA化するためにはビルドが必要です。npmでビルドします。

```
npm run build
```

ビルドすると`dist/`ディレクトリが生成されます。
これでService Workerが登録された状態でビルドされます。

Service Workerの挙動を確認するために[Web Server for Chrome](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb)を導入します。
`dist`のディレクトリにビルドされた諸々のファイルが吐き出されるので、パスを指定して開きます。

<img width="401" alt="スクリーンショット 2018-09-27 23.32.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/269837/bfe87cfb-929d-4bfd-5d5e-e5eb0f437a6b.png">


##Workboxプラグイン
[Workbox](https://github.com/goldhand/sw-precache-webpack-plugin)はPWA化に必要なService Workerをいい感じにしてくれるプラグインです。ページやファイルなど、キャッシュの生存期間を指定することができます。

Workboxをインストールします。

```
npm install workbox-webpack-plugin --save-dev
```

webpackのプラグインなので、設定ファイル変更していきます。

```webpack.prod.conf.js
// const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin')
const workboxPlugin = require('workbox-webpack-plugin') // 追加


// 省略


// 削除
// new SWPrecacheWebpackPlugin({
//   cacheId: 'my-pwa',
//   filename: 'service-worker.js',
//   staticFileGlobs: ['dist/**/*.{js,html,css}'],
//   minify: true,
//   stripPrefix: 'dist/'
// })

// 追加
 new WorkboxPlugin.GenerateSW({
   cacheId: 'easy-wallet',
   globDirectory: config.build.assetsRoot,
   globPatterns: ['**/*.{html,js,css,png}'],
   swDest: path.join(config.build.assetsRoot, 'service-worker.js'),
   skipWaiting: true,
   clientsClaim: true,
   runtimeCaching: []
 })

```

パラメータの概要は以下の通り。

・ skipWaiting
Service Worker が 待っている lifecycle stage をスキップするかどうか

・ clientsClaim
ServiceWorkerがactive状態になった時にすぐにクライアント制御を開始する場合はtrueにする

・ runtimeCaching
キャッシュ戦略、対象ファイルのキャッシュ設定する場合は追加する

もう一度`npm run build`でビルドします。Service Workerのキャッシュが残っているので一度クリアして再読み込みします。

以上です。