これはなに
Vue 3 + Vuetify 3で作成したWebアプリをPWA(Progressive Web Apps)に対応させる方法のまとめ。
環境
- Vue 3.2.45
- Vuetify 3.1.1
- TypeScript 4.9.4
- Vue Router 4.1.6
- Vite 3.2.5
- vite-plugin-pwa 0.14.1
方法
パッケージをインストールする
vite-plugin-pwa をインストールする。
yarn add vite-plugin-pwa -D
VitePWAをプラグインとして追加する
vite.config.tsを編集する。
+ import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
plugins: [
vue({
template: { transformAssetUrls },
}),
vuetify({
autoImport: true,
}),
+ VitePWA({
+ registerType: 'autoUpdate'
+ })
]
})
Service Workerをアプリに登録する
main.tsでService Workerをアプリに追加する。
import App from './App.vue';
// Composables
import { createApp } from 'vue';
// Plugins
import { registerPlugins } from '@/plugins';
+ // Register service worker
+ import { registerSW } from 'virtual:pwa-register';
+ registerSW();
const app = createApp(App);
registerPlugins(app);
app.mount('#app');
このとき、TypeScriptだと、“virtual:pwa-register"という名前のモジュールは存在しないというエラーを吐かれる。 これは"virtual:pwa-register"が型として登録されていないために起こる。 よって、tsconfig.jsonで型情報を追加する。
{
"compilerOptions": {
+ "types": [
+ "node",
+ "vite-plugin-pwa/client"
+ ],
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
+ "node_modules/vite-plugin-pwa/client.d.ts"
],
}
キャッシュするファイルを指定する。
PWAでキャッシュさせるデータにico, png, svgなどを含めたい場合は、workboxのglobPatterns
に含める必要がある。
import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
plugins: [
VitePWA({
registerType: 'autoUpdate',
+ workbox: {
+ globPatterns: ['**/*.{js,css,html,ico,png,svg}']
+ }
})
]
})
アイコン画像を用意する
下記に示す画像をすべて用意する。 内容はすべて同じロゴ画像で問題ない。
- mask-icon.svg
- favicon.ico
- 180 × 180 pxのpng画像(apple-touch-iconとして利用する)
- 192 × 192 pxのpng画像
- 256 × 256 pxのpng画像
- 384 × 384 pxのpng画像
- 512 × 512 pxのpng画像
mask-icon.svgは元のロゴ画像そのままでよい。
260 x 260 pxの画像があれば、 Favicon Generator for perfect icons on all browsers で大体の必要なものは生成できる。
また、512 x 512 pxのpng画像があれば、 PWA Manifest Generator | SimiCart でも192 × 192 px, 256 × 256 px, 384 × 384 pxの画像を生成できる。
favicon.icoはpngファイルからConvertio — ファイルコンバーター でも生成できる。
全ての画像はpublic直下に配置する。
PWAの最低要件を満たさせる
head内に必要情報を追記する
アプリのエントリーポイントとなるファイル(大抵はindex.html)の<head>
タグ内に、下記内容を含めなければならない。
- viewportのmeta情報
- タイトル
- 説明
- favicon
- apple-touch-iconへのリンク
- mask-iconへのリンク
- theme-colorのmeta情報
Favicon Generator for perfect icons on all browsers
を使った場合は、<head>
タグ内に追記すべき内容も生成されるため、それをコピペすればよい。
最低情報だけ列挙すると下記のようになる。
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Example App</title>
<meta name="description" content="Example description">
<link rel="icon" href="/favicon.ico">
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180">
<link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF">
<meta name="theme-color" content="#ffffff">
</head>
筆者の環境では次のようになった。
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FF14 Collections Checker</title>
<meta
name="description"
content="Final Fantasy 14 Collections Checker App"
/>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
</head>
VitePWAの必要事項を設定する
VitePWAの必要事項であるincludeAssets
とmanifest
をvite.config.tsに定義する。
export default defineConfig({
plugins: [
VitePWA({
includeAssets: [
'favicon.ico',
'apple-touch-icon.png',
'mask-icon.svg',
'robots.txt',
],
manifest: {
lang: 'ja',
name: 'Web App Name',
short_name: 'App Name',
description: 'Example description',
theme_color: '#ffffff',
background_color: '#ffffff',
display: 'standalone',
scope: '/',
start_url: '/',
icons: [
{
src: '/icon-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/icon-256x256.png',
sizes: '256x256',
type: 'image/png',
},
{
src: '/icon-384x384.png',
sizes: '384x384',
type: 'image/png',
},
{
src: '/icon-512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: '/icon-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
],
},
}),
],
});
robots.txtの追加
検索エンジンがクロールできるようにrobots.txtを追加する。 publicファイル直下にrobots.txtを作成し、下記を記入する。
User-agent: *
Allow: /
ビルドして確認する
確認には、yarn build && yarn preview
を実行する。
うまくいくと、リンクの横にダウンロードマークが表示される。
なお、vite-plugin-pwaによるPWA機能は、本番環境でないと動作しない。
そのため、yarn dev
では動作しない。
参考文献・URL
- Vite PWA | Vite PWA
- Getting Started | Guide | Vite PWA
- vite-plugin-pwa/vite.config.ts at main · vite-pwa/vite-plugin-pwa
- Vite (React, TypeScript)プロジェクトをPWA化 | 定年後にWeb開発者目指す
- ViteでQRリーダーアプリを作る
- Cannot find name ‘process’ Error in TypeScript | bobbyhadz
- Getting started with PWAs and Vue 3 | Vue Mastery
- Vite を使った Vue 3 プロジェクトのPWA化 | タイトルをここに入力できない