LoginSignup
132
125

More than 3 years have passed since last update.

Vue CLI 3 で PWA チュートリアル(Service Workers / Add to Home Screen / Push Notifications)

Last updated at Posted at 2019-01-19

オリジナル記事
https://blog.n11sh1.com/vue-pwa-tutorial-ja/

PWAとは?

PWA(Progressive Web App) の一部に以下のような機能があります。

  • Service Workers
  • Add to Home Screen
  • Push Notifications

これにより Webアプリ として開発しても Nativeアプリ 同様のUXをユーザーに提供できます。
ここらへんを Vue を使って試していきます。

Ref. Progressive Web Apps | Web | Google Developers
Ref. はじめてのプログレッシブ ウェブアプリ - Google Codelabs

Vue CLI 3 + PWA

デモ
https://vue-pwa-tutorial.firebaseapp.com

ソースコード
https://github.com/n11sh1/vue-pwa-tutorial

環境構築手順

1. Vue CLI のインストール

Ref. Installation | Vue CLI 3

$ npm install -g @vue/cli

2. 新規プロジェクト作成

$ vue create vue-pwa-tutorial

3. マニュアルモードを選択

Vue CLI v3.3.0
? Please pick a preset: 
  default (babel, eslint) 
❯ Manually select features 

4. PWAを選択

Vue CLI v3.3.0
? Please pick a preset: Manually select features
? Check the features needed for your project: 
❯◉ Babel
 ◉ TypeScript
 ◉ Progressive Web App (PWA) Support
 ◉ Router
 ◉ Vuex
 ◯ CSS Pre-processors
 ◉ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

※TypeScript, Router, Vuex の選択はお好みで

5. あとは適当に選択

Vue CLI v3.3.0
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, PWA, Router, Vuex, Linter
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript for auto-detected polyfills? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a linter / formatter config: TSLint
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? Yes
? Save preset as: 

6. プロジェクト作成中…

Vue CLI v3.3.0
✨  Creating project in /Users/zyyx-kubo/WVVUProjects/chatty/vue-pwa-tutorial.
🗃  Initializing git repository...
⚙  Installing CLI plugins. This might take a while...

7. サーバー起動

$ cd vue-pwa-tutorial/
$ npm run serve

8. 開発環境にアクセス

PC
vue-pwa-tutorial.png

SP
ダウンロード1.png

このままでは単なるWebサイトなので、PWAらしくしていきます!

PWA の機能を試す

Service Workers

npm run serve で起動した場合、以下のように Service Workers は動きません。
Developer Tool > Application > Service Workers
vue-pwa-tutorial_と_Web_Server_for_Chrome.png

Service Workers の挙動確認には npm run build でビルドする必要があります。
Web Server for Chrome を使ってビルドされた ./dist ディレクトリを公開すると、以下のように Service Workers が動いていることが確認できます。(Service Workers を使用しない画面の修正などは npm run serve で問題なく動作確認できます)

$ npm run build
 DONE  Build complete. The dist directory is ready to be deployed.

Web_Server_for_Chrome.png

vue-pwa-tutorial2.png
vue-pwa-tutorial3.png
静的コンテンツ(*.html, *.css, *.js, *.png, *.txt)が precache されています。

Developer Tool > Application > Service Workers > Update on reload にチェックを付ければ、リロードの度にキャッシュを更新してくれます。(Cache Storage から対象のファイルを削除でも可)

Add to Home Screen

Web App Manifest

「ホーム画面に追加」のダイアログを表示するには、JSON形式の Web App Manifest ファイルが必要です。
Vue CLI で PWA を選択するとデフォルトで作成されるので、そちらをそのまま使用します。

./public/manifest.json
{
  "name": "vue-pwa-tutorial",
  "short_name": "vue-pwa-tutorial",
  "icons": [
    {
      "src": "./img/icons/android-chrome-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "./img/icons/android-chrome-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "./index.html",
  "display": "standalone",
  "background_color": "#000000",
  "theme_color": "#4DBA87"
}

開発環境

PC
Developer Tool > Application > Manifest > Add to homescreen
vue-pwa-tutorial4.png

chrome://apps/
アプリ.png

SPはこのままだと見えないので、サーバーにデプロイします。

デモ環境(Firebase Hosting)

Firebase を使う理由としては、次に Push Notifications を試すので、そのための布石でもあります。

Ref. Deployment Firebase | Vue CLI 3

1. 新規プロジェクト作成

まずは Firebase console にGoogleアカウントでサインインして、プロジェクトを作成します。
screencapture-console-firebase-google-u-0-2019-01-18-21_39_00.png

2. デプロイ

デプロイはコマンドで実行するので Firebase CLI をインストール

$ npm install -g firebase-tools

ログインする

$ firebase login

プロジェクトルートで初期化

$ firebase init hosting

? Select a default Firebase project for this directory: (Use arrow keys)
  [don't setup a default project] 
❯ vue-pwa-tutorial (vue-pwa-tutorial) 
  [create a new project] 

? What do you want to use as your public directory? (public) dist

? Configure as a single-page app (rewrite all urls to /index.html)? (y/N) y

? File dist/index.html already exists. Overwrite? (y/N) N

デプロイ

$ firebase deploy --only hosting

3. 動作確認

SP
ダウンロード2.png
ダウンロード3.png
ダウンロード5.png
ダウンロード4.png

これで Nativeアプリ 同様にホーム画面にアイコンが追加されました。(アプリストアからインストールする手間も減ります)

静的コンテンツがキャッシュされているので、動作も早いです。(APIなどもキャッシュできるようですが、今回は割愛)

Push Notifications

プッシュ通知には Firebase Cloud Messaging(FCM) を使用します。

Ref. JavaScript Firebase Cloud Messaging クライアント アプリを設定する | Firebase
Ref. JavaScript クライアントでメッセージを受信する | Firebase
Ref. Firebase Cloud Messaging Quickstart | GitHub

1. FCM の Web Push 証明書 を取得

vue-pwa-tutorial_–_設定_–_Firebase_console.png

2. Web App Manifest に gcm_sender_id を追加

./public/manifest.json
{
  ...,
  "gcm_sender_id": "103953800507"
}

3. Firebase SDK のインストール

$ npm install --save firebase

4. Firebaseの設定情報を取得

Firebase console > プロジェクトの設定 > 全般 > アプリ > Web
vue-pwa-tutorial_–_設定_–_Firebase_console2.png

5. 通知の受信許可とトークン取得

src/main.ts に以下のコードを追加

src/main.ts
import * as firebase from "firebase";

var config = {
  apiKey: "xxxxxxxxxxxx",
  authDomain: "xxx.firebaseapp.com",
  databaseURL: "https://xxx.firebaseio.com",
  projectId: "xxx",
  storageBucket: "xxx.appspot.com",
  messagingSenderId: "xxxxxxxxxxxx"
}; // 4をコピペ
firebase.initializeApp(config);

const messaging = firebase.messaging();

messaging.usePublicVapidKey("xxxxxxx"); // 1で取得した鍵ペア

// 通知の受信許可
messaging.requestPermission().then(() => {
  console.log('Notification permission granted.');

  // トークン取得
  messaging.getToken().then((token) => {
    console.log(token)
  })
}).catch((err) => {
  console.log('Unable to get permission to notify.', err);
});

6. FCM 用の Service Worker を追加

FCM では firebase-messaging-sw.js で Firebase メッセージング Service Worker を定義する必要があります。
(あるいは、useServiceWorker を使って既存の Service Worker を指定できます。こちらは割愛)

./public/firebase-messaging-sw.js
// [START initialize_firebase_in_sw]
// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/5.5.6/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/5.5.6/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in the messagingSenderId.
firebase.initializeApp({
  'messagingSenderId': 'xxxxxxxxx' // 4の messagingSenderId をコピペ
});

// Retrieve an instance of Firebase Messaging so that it can handle background messages.
const messaging = firebase.messaging();
// [END initialize_firebase_in_sw]

Push Notification は Service Workerが動いている必要があるので npm run build して Web Server for Chrome で確認します。
http___127_0_0_1_8887_が次の許可を求めています_と_vue-pwa-tutorial.png
vue-pwa-tutorial5.png

7. 動作確認

vue-pwa-tutorial_–_設定_–_Firebase_console6.png

以下の curl でメッセージ受信テスト

$ curl -X POST -H "Authorization: key=${↑のサーバーキー}" -H "Content-Type: application/json" -d '{
  "to": "${5のトークン}",
  "notification": {
    "title": "FCM Message",
    "body": "This is an FCM Message",
    "icon": "./img/icons/android-chrome-192x192.png"
  }
}' https://fcm.googleapis.com/fcm/send

PC
Banners_and_Alerts_と_n11sh1_vue-pwa-tutorial__Vue_CLI_3___PWA_Plugin.png
通知が届きました!
ページがフォアグラウンド(フォーカスされている場合)は、メッセージは届きません。
vue-pwa-tutorial6.png

SP
SPも同様に通知を許可して curl を実行するとプッシュ通知が届きます。(アプリアイコンにも通知ドットが付きます)
ダウンロード6.png
ダウンロード7.png
ダウンロード8.png

まとめ

PWA を使えば Webアプリでも Nativeアプリ に近い UX が提供できます。

今回紹介できていないこともあるので、また機会があれば書きます。

  • Service Workers
    • Cache Control
    • Offline Page
  • Push Notifications
    • Token Refresh
    • Firebase Cloud Messaging

さいごに

個人ブログにオリジナル(日本語&英語)をUPしています。
この記事が良いと感じた方は、そちらにもリアクション頂けると嬉しいです:relaxed:
https://blog.n11sh1.com

132
125
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
132
125