Madogiwa Blog

主に技術系の学習メモに使っていきます。

webpackで管理してるフロントエンドアプリを最低限のPWA対応(ホームに追加して起動)するときのMEMO🕸📦

最近Webpackで管理してるフロントエンドアプリをPWA対応してAndroid環境でホームに追加して起動できるようにしたので、そのへんの対応まわりをメモしておく✍

👇コードだけみたい人はこちら

github.com

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

    • 今回はgithub pagesを使っており、https化されているので問題なしと判断しました。
  • サービスワーカー

    ネットワークのリクエストに介在してネットワークの使用可否の状況に基づいて適切な対応を取ったり、サーバー上にあるアセットを更新したりします。プッシュ通知やバックグラウンド同期の API 群へのアクセスもできるようになります。 https://developer.mozilla.org/ja/docs/Web/API/Service_Worker_API

    • 今回はworkbox-swworkbox-webpack-pluginを使ってコードを生成しました。
  • マニフェストファイル

    PWA のマニフェストには、その名前、作者、アイコン、バージョン、説明、および (他のものの中で特に) 必要なすべてのリソースのリストが含まれています。 https://developer.mozilla.org/ja/docs/Web/Manifest

    • 今回はwebpack-pwa-manifestを使ってコードを生成しました

詳しくはMDNのドキュメントをご確認ください

developer.mozilla.org

サービスワーカー用のスクリプトファイルを生成してサービスワーカーを登録

サービスワーカー用のスクリプトファイルの生成には下記のライブラリを使用しました。

まずはこれらを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を使用しました。

www.npmjs.com

まずは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",  // 開始時に起動するページ
    }),

👇マニフェストファイルの項目の詳細はこちら

www.npmjs.com

この状態で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)多いので、 これから感がありますが既存のウェブアプリを意外とさくっとアプリっぽく出来ていいですね👍

参考

qiita.com

qiita.com

employment.en-japan.com