PWA入門(ReactでPWAを実践)

## はじめに
2023年3月27日にiOS16.4が公開され、iPhoneのPWAでPush通知が受け取れるようになりました。Push通知が解禁された事により、PWAがますます注目されるようになりました。ただ、PWAって具体的に何？技術的にどうやって実現しているの？？って所が不透明だったので、実際に手を動かしながら理解を深めにいこうと思います。

https://webkit.org/blog/13966/webkit-features-in-safari-16-4/

## 環境準備

```sh:環境準備
~/develop/HITOTSU$ npx create-react-app pwa-react-typescript --template cra-template-pwa-typescript

Creating a new React app in /Users/kouji/develop/HITOTSU/pwa-react-typescript.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template-pwa-typescript...


added 1425 packages in 2m

235 packages are looking for funding
  run `npm fund` for details

Initialized a git repository.

Installing template dependencies using npm...

added 40 packages, and changed 2 packages in 12s

235 packages are looking for funding
  run `npm fund` for details

We detected TypeScript in your project (src/App.test.tsx) and created a tsconfig.json file for you.

Your tsconfig.json has been populated with default values.

Removing template package using npm...


removed 1 package, and audited 1465 packages in 1s

235 packages are looking for funding
  run `npm fund` for details

6 high severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

Created git commit.

Success! Created pwa-react-typescript at /Users/kouji/develop/HITOTSU/pwa-react-typescript
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd pwa-react-typescript
  npm start

Happy hacking!
```

## ServiceWorkerの登録
```ts:src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://cra.link/PWA
serviceWorkerRegistration.unregister();　// ここでserviceWorkerを未登録にしている。
```
デフォルトではserviceWorkerは未登録になっています。なので、登録する処理に変更しましょう！！

```ts:変更箇所
// serviceWorkerRegistration.unregister();　// これをコメントアウトして
serviceWorkerRegistration.register() //　これを追加する
```
→これでserviceWorkerが登録されました。では実際に登録できているか確認するため、ログを残しましょう。

<details><summary>ServiceWorker設定確認</summary><div>
serviceWorkerRegistration.tsを下記のように書き換えて登録できているか確認しましょう。

```ts:src/serviceWorkerRegistration.ts
type Config = {
  onSuccess?: (registration: ServiceWorkerRegistration) => void;
  onUpdate?: (registration: ServiceWorkerRegistration) => void;
};

export function register(config?: Config) {
  console.log("serviceWorker 登録します！！")
}

export function unregister() {
  console.log('serviceWorker 未登録です！！')
}
```
</div>
○ServiceWorker未登録時

![スクリーンショット 2023-04-29 13.58.30.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/9db8d277-af9a-d31f-2bb5-c8a1d632d172.jpeg)

○ServiceWorker登録時
![スクリーンショット 2023-04-29 13.58.14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/158b8f05-07a8-17a2-6f8e-7de44f17441b.jpeg)
</details>


## manifest.json
次に`manifest.json`を編集します。`manifest.json`とはローカルにアプリをインストールした際の挙動を定義したものです。とりあえず、`name`、`short_name`を変更します。

```ts:public/manifest.json
{
//  "short_name": "React App",
    "short_name": "Sample PWA",
//  "name": "Create React App Sample",
    "name": "Sample PWA",
  "icons": [
    {
      "src": "favicon.ico",
      "sizes": "64x64 32x32 24x24 16x16",
      "type": "image/x-icon"
    },
    {
      "src": "logo192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "logo512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": ".",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff"
}
```

https://web.dev/add-manifest/

![スクリーンショット 2023-04-29 14.15.05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/47cec0da-be19-f61c-7d15-b1405b2d648b.jpeg)

##　Webブラウザをアプリ化
実はもうアプリケーション化はできています。ここからはブラウザの操作をするだけでアプリにインストール可能です。
![スクリーンショット 2023-04-29 14.26.22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/28a2daf3-e707-81d8-fbf3-6bb43441f1a4.jpeg)

ここまでいくと、アプリケーション化できます！！！
![スクリーンショット 2023-04-29 14.26.49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/72f52353-b575-e4fc-e054-754906df197c.jpeg)

## NextStep
一旦、PWAの実装まで出来ました。今回は、とりあえず作っただけなので、次回以降にPWAに重要な`manifest.json`や`ServiceWorker`、`indexedDB`について解説していきます！！