サンプルコードで学ぶPWA


はじめに

Google I/O 2017の動画を確認し、そろそろPWAについて真面目に把握していかなければと思い至り、GitHubからいくつかサンプルプログラムを探してきて触ってみたので基本的な技術情報と合わせてまとめました。なのでPWA初心者向けです。

特定のJSフレームワークを扱う専門のエンジニアでない限り(私自身がそうなので)、それぞれのJSフレームワークの対応状況なども気になるところだと思いますので、 React.js , Angular , Vue.js の3つにおけるPWAのサンプルについても調べました。

確認した手順などを含めて要点だけまとめていますが、詳細はそれぞれのGitHubページを参照しつつcloneして触ってみて頂ければと思います。

シンプル構成

まずはJSフレームワークなどが入っていないシンプルな構成で、PWAの仕組みについてざっくりまとめました。

PWA retrofit

余計なものが入っていないのでPWAの仕組みを把握するのに適したサンプルという印象。
cloneした後、何もせずともそのまま実行可能。

$ npm start

デフォルトでは http://localhost:8888/ にアクセスするとサンプル画面が表示される。

主な構成

├── favicon.ico
├── (省略)
├── images
│   ├── (省略)
│   └── workbench.jpg
├── index.html
├── js
│   ├── main.js (Service Workerをインストールしているプログラム)
│   └── offlinepage.js
├── manifest.json  (Web App Manifestファイル)
├── offline
│   └── index.html
└── service-worker.js (Service Workerファイル)

Web App Manifest

アプリの情報を記述する。ホーム画面に追加する際のアイコンなどの情報もこのマニフェストファイルの定義に従う。記述方法などの詳細はMDNの Web App Manifest を参照。

なお、manifest.json のファイル名はなんでも良いがアプリを構成するhtmlの <head> にマニフェストファイルへのリンクを記述しておく必要がある。

<link rel="manifest" href="/manifest.json">

Service Workers

PWAの動作を担う実行環境としてインストールされるファイル。以下のように存在チェックして register することでインストールされバックグラウンドでJSを動作させることができる。なお、これもファイル名はなんでも良い。処理的にトップページから最初に呼ばれるJSファイルの冒頭でこの記述をしておくのが定石。とにかくService Workerとして認識させ、インストールしてもらうだけが目的ならファイルの中身は空でも良い。

main.js
// enable service worker
if ('serviceWorker' in navigator) {
  // register service worker
  navigator.serviceWorker.register('/service-worker.js');

  // 省略
}

Service Workerはネットワークリクエストを横取りしてレスポンスを返したり、Push通知を受け取ってNotificationを表示することができる。これによってService Workerが事前にインストールされていれば、オフラインでも画面を表示したり、ページを開いていなくても通知を受け取って通知バーにNotificationを表示することができる。オフライン表示のためにあらかじめ画像などのファイルをキャッシュさせるのもService Workerで行う。

参考

React.js

react-pwa

Simple progressive web app starter kit

と書いてある通り、React.jsを使ったPWAの最小構成。そのままでは「Home Page」とだけ書かれたテンプレート画面が表示されるだけとなっている。

$ npm run build
$ npm start

デフォルトでは http://localhost:3000/ で動作。

最小構成とはいえ、 webpack ベースでテストなどの各種ツールも使う前提となっており、モダンなフロントエンド開発に必要なものはきちんと詰め込まれている印象。またServiceWorkerも、 そのまま実装するのではなく webpack 向けの offline-plugin を使う方式になっており、実用的なテンプレートになっている。

ちなみに、同じ作者がReact.jsのサブセットである Preact を使った同様のサンプルも公開している。

preact-pwa

Material Design Progressive Web App Preact starter kit

と書いてある通り、マテリアルデザインにも対応している模様。ただしそのまま実行しても見た目はreact-pwaと同じテンプレート画面でマテリアル感は無かったのでスクリーンショットは割愛。

react-pwa-reference

Express, Fluxible などのトレンド技術をひとしきり詰め込んである印象。サンプルとしてパッケージ化されて開発に使う npm タスクも一覧にまとまっているので、軽く触ってみる範囲で困ることはない。ひとまず以下で試すことができる。

$ npm install
$ npm run dev

デフォルトは http://localhost:3000/ で動作。

公式によると使っているものは以下のような感じ。

Node
Express
React (Facebook)
Fluxible (Yahoo)
sw-toolbox, sw-precache (Google)
babel6, gulp4, webpack, eslint, mocha/chai, sass

ServiceWorker周りは sw-toolbox , sw-precache を使っている。これらはGoogleが公開している Service Worker Libraries のライブラリである。

このほかテストツールなども含めてひとしきりのツールがぎっしりつまっていて初心者は見ただけで圧倒されるが、デモ画面を見るとわかるようにサンプルの完成度が高いので、これらのツール類を使ったアプリの完成形はイメージしやすい。

参考

Fluxible + React の概要をまとめた
GoogleChrome/sw-precache が便利そう

Angular

Progressive Hacker News client built with Angular

Progressive Hacker News のサイトをAngular2でPWA化している。

$ npm install
$ npm start

デフォルトは http://localhost:4200/ で動作。

ServiceWorkerは sw-toolbox , sw-precache を使っている。一応レスポンシブをうたっていて、デスクトップも合わせて扱う場合のPWAの事例としても参考になるかもしれない(サンプル上は見た目はあまり変わらない)。

NG-Pokedex

Angular2 でPWA化されたポケモン図鑑。 angular-cli を使う方式のため、まずはインストールが必要。

$ npm install -g angular-cli@latest

あとはコマンド1つでひとまず動作する。

$ ng serve

デフォルトは http://localhost:4200/ で動作。

ServiceWorkerは Workbox を使っている。また、通知周りは firebase にデプロイする仕組みも含まれている。

参考

Fast Offline Angular Apps with Service Workers

補足

AngularはAngular CLI と Angular Mobile ToolKit などのツール類もPWAをサポートする前提で充実してきている印象。ただし4系以降ではもっと力を入れるとも言われているのでまだまだ動きがありそう。

Angular最新トピックとテクニックをng-japan代表のlacoさんに聞いてきた!(後編)

Vue.js

Vue Simple PWA

Simple Progressive Web App Example Built With Vue.js.

Vue.jsで作られたシンプル構成のPWA。デモページ も公開されている。

$ npm install
$ npm run dev

http://localhost:8080/ で動作する。

ServiceWorkerまわりは Cach APIで未実装部分だったAPIを補うための cache-ployfill が含まれているなどやや古い実装の印象(Chrome46以降はこれは不要)。

参考

Service Worker の紹介
Chrome 46 に Cache.addAll() を実装した

vue-pwa-boilerplate

Google I/O 2017のProduction Progressive Web Apps With JavaScript Frameworks のセッションで紹介された Vue.jsでPWAを作るためのテンプレート。

vue-cli を使うため未インストールの場合はまず npm install しておく

$ npm install -g vue-cli@latest

git clone してきたテンプレート(ここでは pwa )を使って vue-cli でプロジェクトを作成する。

$ vue init pwa my-project

作成したプロジェクトをビルドして実行する

$ cd my-project
$ npm install
$ npm run dev

実行すると自動でブラウザが起動し http://localhost:8080/ を呼び出す。

ServiceWorkerは前出の sw-precache のWebPack向けラッパーである sw-precache-webpack-plugin を使って実装している。また、Vue.jsのプロジェクトを構成する(テスティングフレームワークなども含む)標準的な要素一式が揃っていおり、テンプレートながらキャプチャのようにサンプル用の画面も実装されているので、これからVue.jsを使ってPWAを作りたい場合は周辺のライブラリの使い方も含めて完成形がイメージしやすい。

まとめ

PWAの仕組みを実装レベルで把握しようと思ってGitHub上のサンプルプログラムを巡ってみました。が、JSフレームワークでの実装例を調べ始めると、移り変わりの激しいモダンなフロントエンド系技術を色々目の当たりにすることになり、(私のようにこの領域の専門ではないエンジニアにとっては)思った以上に把握に時間を要しました。とはいえ、実際に導入するとなるとReact.jsにするかAngularにするかといった所から検討したり、 Service Worker Libraries などの活用を検討すると思いますで、これらのサンプルの存在はその助けになると思います。変化が激しいだけにサンプルは多数ありますが、便利なCLIやnpmなどでパッケージ化された仕組みは充実しています。ローカルで動かしてみるだけならコマンドを数回叩くだけだったりするので、非常に良い時代だなと思いました。

Angularではつい先日バージョン4.2がリリースされたのに合わせて 公式サイト 自体がServiceWorkerを活用してPWA対応しているようです。このようにPWAの動向的には今後も色々動きがありそうですが、現時点では各フレームワークが対応できておりライブラリもこなれているので、PWAを導入するうえで大きな障壁は無いと思われます。ただ、PWAを含めた周辺のフロントエンド開発自体がまだ技術的に過渡期で今後も様々な変化が起こると考えられるため、現時点でどのような選択をしたとしても今後も変化に追従していく覚悟は必要だと思われます。