とりあえずPWAを試すための自分用メモ -インストール可能にする-

「細かい事は後回しで、まずは動くものを作りたい！」をするための自分用のメモです。

細かい事は以下のリンク先を参照してください。

- [プログレッシブウェブアプリ (PWA)](https://developer.mozilla.org/ja/docs/Web/Progressive_web_apps)
- [Learn PWA](https://web.dev/learn/pwa/)


まずはWebアプリをインストール可能にするところからスタートします。

今回の内容は[ここ](https://developer.mozilla.org/ja/docs/Web/Progressive_web_apps/Installable_PWAs)に詳細が書いてます。

## 必要なもの
Webアプリをインストール可能にするためには以下のものが必要です。

- マニフェストファイル
- サービスワーカー
- `index.html` ファイル
- `https` でのホスティング(`http` では不可能)

今回はWindows版のChromeでしか試していないので AndroidやiOSなどでは未検証です。

### マニフェストファイル
アプリをPWAで動かすために必要なメタ情報が書かれているファイルです。

`webmanifest` というファイルを使うそうですが、現状は`manifest.json` という名前が多く使われているらしい

それぞれのフィールドが意味するものの詳細は[ここ](https://developer.mozilla.org/ja/docs/Web/Manifest)に書かれているので、プロダクション運用する場合は確認しておいてください。

今回はとりあえず動かしたいので [ここ](https://www.simicart.com/manifest-generator.html/) のジェネレーターを使います。(FireFoxだと動かなかったのでChromeを使いました。)
これ以外にも`manifest.json generator` などで検索すればいろいろ出てきます。

|項目         |入力値        |
|------------|--------------|
|Name        |my-qiita-pwa  |
|Short Name  |Qiita用PWA    |
|Display     |Standalone    |
|Description |Qiita用アプリ  |
|Application Scope   |/     |
|Start URL   |/index.html   |
|Theme Color |#f69435       |
|Background Color    |#ffffff  |
|Icons       |(任意の画像)   |

入力後に「GENERATE MANIFEST」ボタンをクリックすると`manifest.zip` ファイルがダウンロードされます。

中には リサイズされたアイコンとマニフェストファイルが入っているので展開してください。


### サービスワーカー
メインのスレッドとは別のスレッドで動いており、httpのリクエストに割り込んでキャッシュを返したりすることができるようになります。またDOMには直接アクセスできません。

くわしい説明は[こちら](https://developer.mozilla.org/ja/docs/Web/API/Service_Worker_API)や[こちら](https://developer.mozilla.org/ja/docs/Web/Progressive_web_apps/Offline_Service_workers)をお読みください😅

とりあえず空のキャッシュエントリを作るファイルを用意しておきます。

``` js:sw.js
const cacheName = "my-qiita-pwa-v1";

self.addEventListener("install", (e) => {
  console.log("サービスワーカーがインストールされました！");

  const cachePaths = [];

  e.waitUntil(
    caches.open(cacheName).then((cache) => {
      return cache.addAll(cachePaths);
    })
  );
});

self.addEventListener("fetch", (e) => {
  //httpリクエストの時に呼ばれる
  //ここでキャッシュがあれば返す実装をすることができる。
});

```

サービスワーカーは ウィンドウとは別のところで実行されていて `this` みたいなものが `self` でアクセスできるようになっています。 説明は[このあたり](https://developer.mozilla.org/ja/docs/Web/API/WorkerGlobalScope/self)

`e.waitUntil` には `Promise`を渡すことができます。この中の`Promise`が完了するまで インストールは待機しています。

`caches` でキャッシュにアクセスすることができます。
細かい説明は省略します。 ここでは `cachePaths` のリクエストに対するレスポンスの内容をキャッシュしています。
が、今回は何もしていません。

### index.html
エントリポイントとなるファイルです。

マニフェストファイルの読み込みとサービスワーカーの登録を行います。

``` html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>PWA</title>
    <!-- マニフェストファイルの読み込み -->
    <link rel="manifest" href="./manifest.webmanifest" />
    <script>
      window.addEventListener("load", () => {
        //service workerの登録
        if ("serviceWorker" in navigator) {
          navigator.serviceWorker.register("./sw.js");
        }
      });
    </script>
  </head>
  <body>
    PWAだよ！
  </body>
</html>
```


### `https` でのホスティング

現在のルートフォルダの中身は以下のようになっています。
```
icon-192x192.png
icon-256x256.png
icon-384x384.png
icon-512x512.png
index.html
manifest.webmanifest
sw.js
```

本来は`https`でホスティングする必要がありますが、`localhost` に限り `http` が許容されています。
今回は `Node` の [serve](https://github.com/vercel/serve) を使ってホスティングします。
別に`localhost` でホスティングできるものがあれば `apache` や`IIS` などを使ってもらっても大丈夫だと思います。(未検証)

ルートディレクトリで以下のコマンドを実行します。(`Node.js` はインストールしておいてください)

```
npx serve
```

サーバーが起動した後は `http://localhost:3000` にアクセスしてください。(クリップボードにURLがコピーされているはずです。)

## インストールする

問題なく実装できていればアドレスバーに下のキャプチャのような アイコンが表示されるはずです。
![qiita-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628749/25bf52ae-752e-ecef-f0f2-659ca9959ba1.png)

このアイコンをクリックします。

![qiita-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628749/6a6ba799-601e-f457-bfa9-b323fd01d63d.png)

すると インストールするかを問われるのでインストールしてください。

![qiita-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628749/a0a6d5fc-5e3d-fdcd-cfd3-9961f34d0620.png)

インストールすると別ウィンドウでアプリが立ち上がります。
デスクトップにもショートカットが作成されているはずです。


アプリを削除するには `Chrome` の場合はアドレスバーに `chrome://apps` と入力すれば
アプリの一覧に今回追加したものが表示されているのでそこから削除してください。

## おわりに
以上の手順でとりあえず 動くものは作れるはずです。
ただキャッシュをしていないので オフラインでは動きません。

かなり詳細は端折っていますが、まずはとっかかりにでもなればと思います。