はじめに
前回、indexedDB
を使ってTodoアプリを作ってみました。
Todoなのでしょっちゅう確認したり更新したりするので、アクセス頻度は自ずと高くなりますよね
常にPCを持ち歩くわけにもいかず、ブックマークしてもスマホのブラウザではやっぱり使いにくい...
っということで、今回はこのTodoアプリを PWA
化してスマホでネイティブアプリと同じ感じで使えるようにしてみたいと思います。
前回の記事はこちらです。
PWAとは
PWA
について簡単に紹介しておきましょう
PWA って何?
私は、ちょうど1年くらい前に PWA
を知りました。スマホ向けのアプリを試作する機会があり、
App StoreやGoogle Playを通さずに試作版を試してみたいというニーズからWebアプリで
ネイティブアプリの様な使い方はできないものかと色々調べ、PWA
という技術に出会いました。
ちょっと大仰に書きましたが、PWA
とは
Progressive Web Application の略でネイティブアプリの様に動作させられるWebアプリのことです。
その特徴を簡単に言うなら
- 素早いレスポンス
- オフライン対応
- ホーム画面へのアイコン追加
といったところでしょうか
っで、どんな技術?
PWA
は ServiceWorker
という技術で成り立っています。この ServiceWorker
とは、ブラウザがそのUIとは別にバックグランドで動作させるスクリプトのことです。
っと言われてもピンとこないと思いますが、
ブラウザとWebサーバーの中間に居て、ブラウザからのネットワークリクエストやWebサーバーからのレスポンスをキャッシュしたり、Webからのプッシュ通知を受け付けたり、といろんなことをやってくれる
ブラウザのバックグランドタスクみたいにイメージすると理解しやすいかもしれません。
詳しくは
Service Workers: an Introduction | Web Fundamentals | Google Developers
に説明があります。
この ServiceWorker
を使うには
- ブラウザがサポートしていること
- HTTPS通信であること
という条件があります。
大半のブラウザは既にサポートされているようですが、 詳しくは以下のサイトで確認できます。
Is service worker ready?
HTTPS通信はWebサイトに依存しますが、今回の記事で紹介するサンプルは github.io
を使っています。
Vue
のアプリを github.io
で公開する方法は後述します。
出来上がりはこんな感じです
iphoneのホーム画面にアイコンを追加、アプリを起動させるとこんな感じになります。
アプリをPWA対応にするには
では、前回のTodoアプリを PWA
に対応させてみましょう。
ちょっとその前に...
さきほど、PWA
は ServiceWorker
という技術で成り立っていると説明しました。
上述した通り ServiceWorker
は、ブラウザとWebサーバーの中間に居てリクエストとレスポンスをキャッシュしてオフライン時の動作を可能にしますが、実はこのキャッシュポリシーが ServiceWorker
の実装上の一つの課題になっています。
キャッシュすべき情報はアプリによって様々なのと何をキャッシュし、いつ消去するかといった設計上の画一的ルールはないため、本来はアプリの設計者がユースケースに応じて決めなければなりません。
さらに ServiceWorker
は定型的なロジックが多く、ライフサイクルの状態遷移が複雑なこともあり実装には何かと手間がかかります。
実はそういった煩わしさを軽減するライブラリがあり、Googleが提供する Workbox
もそういったライブラリの一つです。
Vue
では vue cli
が Workbox
を使って ServiceWorker
を自動生成してくれるのでとても簡単に PWA
に対応させることができます。
最初からPWAでやる
vue create
でプロジェクトを作成するときに PWA
を指定します。
こんな感じです。
Manual Selectを選択し
Progressive Web App(PWA) Support をチェックします。
既存のアプリをPWAにする
プロジェクトフォルダ内で vue add @vue/pwa
とすることで既存のアプリを PWA
対応にできます。
コマンドを実行するとこんな感じでPWA
関連のファイルがインストールされます。
PS C:\Shikataramuno\vue-ts-indexed-db-as-pwa> vue add @vue/pwa 📦 Installing @vue/cli-plugin-pwa... > core-js@2.6.9 postinstall C:\Shikataramuno\vue-ts-indexed-db-as-pwa\node_modules\core-js > node scripts/postinstall || echo "ignore" vue-ts-indexed-db-as-pwa@0.1.0 C:\Shikataramuno\vue-ts-indexed-db-as-pwa `-- @vue/cli-plugin-pwa@3.8.0 `-- workbox-webpack-plugin@3.6.3 +-- babel-runtime@6.26.0 | +-- core-js@2.6.9 | `-- regenerator-runtime@0.11.1 +-- json-stable-stringify@1.0.1 `-- workbox-build@3.6.3 +-- common-tags@1.8.0 +-- fs-extra@4.0.3 +-- joi@11.4.0 | +-- hoek@4.2.1 | +-- isemail@3.2.0 | `-- topo@2.0.2 +-- lodash.template@4.4.0 | +-- lodash._reinterpolate@3.0.0 | `-- lodash.templatesettings@4.1.0 +-- pretty-bytes@4.0.2 +-- stringify-object@3.3.0 | +-- get-own-enumerable-property-symbols@3.0.0 | `-- is-regexp@1.0.0 +-- strip-comments@1.0.2 | +-- babel-extract-comments@1.0.0 | | `-- babylon@6.18.0 | `-- babel-plugin-transform-object-rest-spread@6.26.0 | `-- babel-plugin-syntax-object-rest-spread@6.13.0 +-- workbox-background-sync@3.6.3 +-- workbox-broadcast-cache-update@3.6.3 +-- workbox-cache-expiration@3.6.3 +-- workbox-cacheable-response@3.6.3 +-- workbox-core@3.6.3 +-- workbox-google-analytics@3.6.3 +-- workbox-navigation-preload@3.6.3 +-- workbox-precaching@3.6.3 +-- workbox-range-requests@3.6.3 +-- workbox-routing@3.6.3 +-- workbox-strategies@3.6.3 +-- workbox-streams@3.6.3 `-- workbox-sw@3.6.3 ✔ Successfully installed plugin: @vue/cli-plugin-pwa 🚀 Invoking generator for @vue/cli-plugin-pwa... 📦 Installing additional dependencies... vue-ts-indexed-db-as-pwa@0.1.0 C:\Shikataramuno\vue-ts-indexed-db-as-pwa `-- register-service-worker@1.6.2 ✔ Successfully invoked generator for plugin: @vue/cli-plugin-pwa The following files have been updated / added: public/img/icons/android-chrome-192x192.png public/img/icons/android-chrome-512x512.png public/img/icons/apple-touch-icon-120x120.png public/img/icons/apple-touch-icon-152x152.png public/img/icons/apple-touch-icon-180x180.png public/img/icons/apple-touch-icon-60x60.png public/img/icons/apple-touch-icon-76x76.png public/img/icons/apple-touch-icon.png public/img/icons/favicon-16x16.png public/img/icons/favicon-32x32.png public/img/icons/msapplication-icon-144x144.png public/img/icons/mstile-150x150.png public/img/icons/safari-pinned-tab.svg public/manifest.json public/robots.txt src/registerServiceWorker.ts package.json src/main.ts You should review these changes with git diff and commit them.
とっても簡単ですね!
アプリを公開するには
上述したとおり、PWA
は https
でなければなりません。
既に、そのようなサイトを公開されている場合は別ですが、これから https
サイトを新たに公開するとなると何かと手間がかかるのではないかと思います。
ここでは、手軽に https
で試す方法として github.io
で公開するやり方を紹介します。
まず、
GitHub
上に公開ページ用にリポジトリを作ります。docs
フォルダ以下に公開用の一連のファイルをコピーし、GitHub
にpush
します。GitHub
のリポジトリページ上で、[Setting]→[GitHub Pages]→[Source]
で、[master branch/docs folder]
を指定します。そうすると、https://ユーザー名.github.io/リポジトリ名/
というURLで公開できます。
基本、これだけです!
では、前回記事の
https://github.com/Shikataramuno/vue-ts-Indexed-DB.git
をビルドしてアップしてみましょう。
っとここでもその前に若干の修正が必要です。
Vue
では production
モードのビルドでは、公開用ファイルの出力先が dist
フォルダで、URLのルートからのパスで公開用ファイルが生成されます。
github.io
で公開する場合、プロジェクト名のサブフォルダがアプリのルートになるので、そのままでは正しく表示されません。
そこで、プロジェクトフォルダの直下に vue.config.js
というコンフィグ用のファイルを作成し、以下の内容を記述しておきます。
module.exports = { publicPath: process.env.NODE_ENV === 'production' ? '/vue-ts-indexed-db-as-pwa/' : '/', outputDir: 'docs', };
これで npm run build
して docs
フォルダ以下を Github
に push
すれば、正しく表示されます。
このサイトを参考にさせていただきました。
Vue CLI 3 で PWA のアプリつくって GitHubPages で公開 - Qiita
出来上がり!
実際にスマートホンで以下QRコードを読み取りアクセスしてみてください。
ちなみにアクセス先は以下です。
https://shikataramuno.github.io/vue-ts-indexed-db-as-pwa/
Todoアプリが表示されると思います。
ホーム画面に追加するとアイコンが表示されます。これをクリックするとネイティブアプリの様にTodoアプリが起動し、
通常と同じ操作ができるようになると思います。試してみてください。
こんな感じです。
さらに!
機内モードにしてアプリを起動してみてください。
通常通りの操作が可能と思います。オフラインでもTodoの確認、追加、変更、削除が可能です。
これって地味にすごい!って感じですね indexedDb
+ PWA
の威力でしょう!
(やっぱりTodoアプリはこうじゃないとね!)
謝辞
今回は indexedDB
を使ったTodoアプリを PWA
対応にしてみました。
URLにアクセス、ホーム画面に追加したらネイティブアプリと遜色ない使い心地でよかったです。
最近何かと PWA
が話題ですが、ストアを経由せずともアプリをインストールできるので手軽かつ
once write run anywhereが実現できるので色々と重宝しそうです。
最後まで読んでいただき、ありがとうございました。
皆様の何かのお役に立てたなら幸いです。