環境
- Node.js v22
- vite 5.3
viteでビルドされるプロジェクト環境が前提となる。
やりたいこと
どっちお得くんというサイトをスマホから使う際、 ネイティブアプリっぽくさせたかったのでPWAを導入することにした。
今回はvite環境なら一発でPWA化できるということでPWA Vite Pluginを使ってみる。
PWAについて
PWAってのは、Webアプリをネイティブアプリっぽく動かすための技術であり、必要なファイルは主に2つ。service worker
とmanifest.json
。
service worker (dev-sw.js)
は、バックグラウンドで動くスクリプトで、キャッシュやプッシュ通知を制御する。
ブラウザの裏でこっそり動いて、オフラインでも動くようにしたり、アプリっぽい挙動を可能にする。
ネットワークリクエストをインターセプトして、キャッシュからレスポンスを返したり、サーバーにリクエストをフォワードしたりする。
この制御を間違えると、キャッシュが古いままになったり、最悪動かなくなる。
manifest.json
は、PWAアプリの設定ファイル。
アプリの名前、アイコン、テーマカラー、表示モードなどを記述する。
ブラウザがこれを読んで、PWAをホーム画面に追加するときに使う。
icons
セクションで、さまざまな解像度のアイコンを定義する。
display
をstandalone
にすると、ブラウザのUIなしでアプリみたいに表示される。
theme_color
は、アプリのテーマ色だ。これらを設定しないと、PWAとしてインストールできない。
手順
インストール
npm install -D vite-plugin-pwa
vite.config.tsに以下追記
import { VitePWA } from 'vite-plugin-pwa' export default defineConfig({ plugins: [ VitePWA({ registerType: 'autoUpdate', devOptions: { enabled: true, // 開発環境でもPWA有効化 }, }), ],
開発サーバーを起動しChromeのデベロッパーツールで「Application」タブ→「Service workers」を開く。
以下のようになっていれば成功。
アイコンの準備
Webマニフェストの設定が不十分であるためPWAとしてインストールできない。 色々設定項目があるがそのなかにアイコンを用意しなくてはいけない。なんと6種類!!
面倒すぎると思ったが正方形の画像さえ用意すれば自動生成してくれるツールがあった。
ツールのインストール
npm i @vite-pwa/assets-generator -D
pwa-assets.config.tsを作成して以下 今回はpublic/icon.pngに正方形の画像を用意した。
import { defineConfig } from '@vite-pwa/assets-generator/config' export default defineConfig({ images: [ 'public/icon.png' ], })
実行
npx pwa-assets-generator --preset minimal-2023
出力された内容をvite.config.tsに追記しつつ以下のようにする
export default defineConfig({ plugins: [ react(), vanillaExtractPlugin(), VitePWA({ registerType: 'autoUpdate', devOptions: { // 開発環境でもPWA有効化 enabled: true }, manifest: { name: 'どっちお得くん', short_name: 'どっちお得くん', description: '物価上昇を耐え抜け', theme_color: '#ffffff', display: 'standalone', icons: [ { src: 'pwa-64x64.png', sizes: '64x64', type: 'image/png' }, { src: 'pwa-192x192.png', sizes: '192x192', type: 'image/png' }, { src: 'pwa-512x512.png', sizes: '512x512', type: 'image/png' }, { src: 'maskable-icon-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' } ] } }) ] });