最近Webpackで管理してるフロントエンドアプリをPWA対応してAndroid環境でホームに追加して起動できるようにしたので、そのへんの対応まわりをメモしておく✍
👇コードだけみたい人はこちら
- PWA(プログレッシブウェブアプリ)とは
- サービスワーカー用のスクリプトファイルを生成してサービスワーカーを登録
- マニフェストファイルを生成する
- おまけ:iOSの表示を制御する(Not PWA)
- おわりに
- 参考
PWA(プログレッシブウェブアプリ)とは
Progressive web apps (PWA) は、新しいウェブ API と伝統的なプログレッシブな拡張戦略を使用して、クロスプラットフォームのウェブアプリケーションにネイティブアプリと同様の使い勝手をもたらすウェブアプリのことです。 https://developer.mozilla.org/ja/docs/Web/Progressive_web_apps
ウェブアプリケーションをネイティブアプリっぽく使うための拡張でPWAと呼ぶには技術的に下記の要素を持つことが必要なようです。
安全なコンテキスト (HTTPS)
(HTTPS / TLS を介して) コンテンツが安全に配信され、安全ではないコンテキストとの通信の可能性が限られているという合理的な確信がある Window、または Worker のことです。多くのウェブ API が安全なコンテキストでのみ利用可能です。 https://developer.mozilla.org/ja/docs/Web/Security/Secure_Contexts
サービスワーカー
ネットワークのリクエストに介在してネットワークの使用可否の状況に基づいて適切な対応を取ったり、サーバー上にあるアセットを更新したりします。プッシュ通知やバックグラウンド同期の API 群へのアクセスもできるようになります。 https://developer.mozilla.org/ja/docs/Web/API/Service_Worker_API
- 今回は
workbox-sw、workbox-webpack-pluginを使ってコードを生成しました。
- 今回は
マニフェストファイル
PWA のマニフェストには、その名前、作者、アイコン、バージョン、説明、および (他のものの中で特に) 必要なすべてのリソースのリストが含まれています。 https://developer.mozilla.org/ja/docs/Web/Manifest
- 今回は
webpack-pwa-manifestを使ってコードを生成しました
- 今回は
詳しくはMDNのドキュメントをご確認ください
サービスワーカー用のスクリプトファイルを生成してサービスワーカーを登録
サービスワーカー用のスクリプトファイルの生成には下記のライブラリを使用しました。
workbox-swGoogleが出しているサービスワーカー用のコード生成を支援してくれるライブラリworkbox-webpack-pluginworkboxをwebpackから使用するためのプラグイン
まずはこれらをinstallしていきます📦
npm install --save-dev workbox-sw workbox-webpack-plugin
そしてwebpack.config.jsを下記のような感じで修正します。
※今回はdist配下にservice-worker.jsという名前で出力するようにしています。
const workBoxWebpackPlugin = require("workbox-webpack-plugin"); const OUTPUT_PATH = `${__dirname}/dist`; module.exports = { // ... 省略 plugins: [ // PWA用のservice-worker.jsを生成 new workBoxWebpackPlugin.GenerateSW({ swDest: OUTPUT_PATH + "/service-worker.js" }),
この状態でwebpackを実行すると下記のような形でservice-worker.jsと関連ファイルが生成されます✨
$ ls dist/
index-35ccbfc3e6ee670c355d.css service-worker.js
index-35ccbfc3e6ee670c355d.js service-worker.js.map
index.html workbox-64f1e998.js
workbox-64f1e998.js.map
そしてサービスワーカーを登録するためには生成されたjsを読み込むようにentryのjsで下記を実行するようにします。
if ("serviceWorker" in navigator) { window.addEventListener("load", () => { navigator.serviceWorker.register("./service-worker.js"); }); }
これでサービスワーカーの準備が出来ました🙆♂️
マニフェストファイルを生成する
マニフェストファイルの生成にはwebpack-pwa-manifestを使用しました。
まずはinstallします📦
npm install --save-dev webpack-pwa-manifest
そしてwebpack.config.jsを下記のような感じで修正します。
const workBoxWebpackPlugin = require("workbox-webpack-plugin"); const WebpackPwaManifest = require("webpack-pwa-manifest"); const OUTPUT_PATH = `${__dirname}/dist`; module.exports = { // ... 省略 plugins: [ // PWA用のservice-worker.jsを生成 new workBoxWebpackPlugin.GenerateSW({ swDest: OUTPUT_PATH + "/service-worker.js" }), // PWA用のmenifest.jsonを生成 new WebpackPwaManifest({ short_name: "short name", // ホーム画面のラベルに表示される名称 name: "app full name", // appの名前 display: "standalone", // standaloneにするとブラウザのUI要素が削除されてアプリっぽくなる start_url: "index.html", // 開始時に起動するページ }),
👇マニフェストファイルの項目の詳細はこちら
この状態でwebpackを実行すると下記のような形でmanifest.jsonが生成されます✨※最初からdigestが付与されていて便利
$ ls dist/
index-35ccbfc3e6ee670c355d.css service-worker.js
index-35ccbfc3e6ee670c355d.js service-worker.js.map
index.html workbox-64f1e998.js
manifest.ababbbaae2b52862d5cbfb8aefc3af66.json workbox-64f1e998.js.map
こんな感じのmanifest.jsonが生成されます⚙
{ "name": "app full name", "short_name": "short name", "orientation": "portrait", "display": "standalone", "start_url": "index.html" } // "orientation": "portrait"は縦の向きを表しているようです。 // > the "portrait" enum represents the portrait orientation // > https://www.w3.org/TR/screen-orientation/#screenorientation-interface
これでmanifest.jsonも生成され、PWAを最低限使う準備が出来ました🙌
おまけ:iOSの表示を制御する(Not PWA)
iOSではPWAは未対応なのですが、Safariからホームへ追加した際の挙動を制御することができるようです。
htmlのhead内に下記を追加するとホームに追加したときの挙動を制御できるようです👀
<head> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,user-scalable=no"> <!-- URLバー等を消してアプリのように見せる --> <meta name="apple-mobile-web-app-capable" content="yes"> <!-- ステータスバーのデザイン --> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <!-- ホームに追加したときの名前 --> <meta name="apple-mobile-web-app-title" content="App Name"> </head>
おわりに
PWA対応、ネイティブアプリに比べると色々と制約が多そう + まだ対応していないものが(特にios)多いので、 これから感がありますが既存のウェブアプリを意外とさくっとアプリっぽく出来ていいですね👍