こちらはVue.js #1 Advent Calendar 2017 - Qiita 7日目の記事です。

最近盛り上がっているPWAを試す際に、Nuxt.jsを使うと非常に簡単に実現できそうだったので、その方法を紹介しようと思います。

はじめに

PWAとは

Progressive Web Appの略で、Webの技術を使って、スマホアプリっぽい挙動を実現できる技術です。 厳密に言うと複数のWeb技術の集合体なのですが、導入としては下記がよく取り扱われます

  • オフライン対応
  • Web通知(ブラウザに通知)
  • ホーム画面への追加とスプラッシュ画像

上記は今までネイティブアプリやハイブリッドアプリ、側ネイティブ等iOSやAndroidのプラットフォームに載せるアプリケーションとして開発し、展開していました。 これが、Web上でできることによって、オーガニック流入からシームレスにアプリケーションを起動、その後のリテンションまでWebの技術だけで実現できるようになります。

ネイティブアプリ、Webアプリそれぞれのいいとこ取りをしている技術ということで、いくつかの技術は前から実装されてきていましたが、モバイル系のブラウザが対応してきたり、Safariが実装段階に入ったりと、環境としても整い始め注目度が増しています。

Nuxt.jsとは

こちらの記事](http://techblog.scouter.co.jp/entry/2017/11/13/120000)でも紹介させていただきましたが、Vue.jsで動くUniversalアプリケーション[フレームワークです。 今回はNuxt.jsの特徴であるModuleを使い、PWAを触っていこうと思います。

導入する

Nuxt.jsはVue cliを使うとかんたんに導入できるので、今回はコチラを使おうかと思います。

1
2
$ yarn global install vue-cli
$ vue init nuxt-community/starter-template pwatest

とすると下記のようなファイルがpwatestに生成されます

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
pwatest/
├── README.md
├── assets
│   └── README.md
├── components
│   ├── Logo.vue
│   └── README.md
├── layouts
│   ├── README.md
│   └── default.vue
├── middleware
│   └── README.md
├── nuxt.config.js
├── package.json
├── pages
│   ├── README.md
│   └── index.vue
├── plugins
│   └── README.md
├── static
│   ├── README.md
│   └── favicon.ico
└── store
    └── README.md

次に、PWAモジュールをインストールします。

1
yarn add '@nuxtjs/pwa'

そして、nuxt.config.jsを下記のように設定します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
  build: {
    /*
    ** Run ESLint on save
    */
    extend (config, ctx) {
      if (ctx.dev && ctx.isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
-  }
+  },
+  modules: [
+    '@nuxtjs/pwa'
+  ],
+  workbox: {
+    dev: true, //開発環境でもPWAできるように
+  }
}

あとはビルドして、サーバー立ち上げれば終わりです

1
2
nuxt build
nuxt start

デベロッパーツールを見ると、ServiceWorkerが動いていることが確認できます。

このままオフラインにしても、正常に表示されます。

なぜなにも設定せずにこのようにキャッシュがされるかというと PWAモジュールはデフォルトでNuxt.jsに最適化された下記のようなキャッシュ戦略を持っているためです。

  • nuxt buildで生成されるjsファイル: precache
  • /_nuxt/*パスのファイル: cacheFirstでキャッシュ
  • /*パスのファイル(staticにある静的ファイル等): networkFirstでキャッシュ

もちろんこれ以外に設定することも可能で、たとえば、tumblr.comの画像をcacheFirstでキャッシュしたい場合は下記の用にnuxt.config.jsに設定します。

1
2
3
4
5
6
7
8
9
+  workbox: {
...
+    runtimeCaching: [
+      {
+        urlPattern: 'https://*.media.tumblr.com/*',
+        handler: 'cacheFirst',
+        method: 'GET',
+      },
+    ],

webプッシュの導入

PWAモジュールにはwebプッシュももちろん導入されています。 webプッシュサーバーを自前で用意してもいいですが、お手軽導入ということでOneSignalを使って導入してみましょう。

OneSignal上でアプリケーションを登録後、

1
yarn add '@nuxtjs/onesignal'

をし、nuxt.config.jsを下記のように設定します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
  },
  modules: [
+    '@nuxtjs/onesignal', // pwaの前に定義
    '@nuxtjs/pwa'
  ],
  
+  oneSignal: {
+    init: {
+      appId: '設定したappId',
+      allowLocalhostAsSecureOrigin: true,
+      welcomeNotification: {
+        disable: true
+      }
+    }

再度ビルド、サーバー立ち上げを行います。 OneSignalのコンソールからメッセージを送信すると下記のようにwebプッシュが送信されます

manifestの設定

Android等のモバイル端末で、ホーム画面に追加すると、アプリっぽい挙動になるmanifestの実装も下記のようにnuxt.config.jsに設定するだけです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
+  manifest: {
+    name: 'PWATest',
+    short_name: 'PWA',
+    title: 'PWATest',
+    'og:title': 'PWATest',
+    description: 'PWATest',
+    'og:description': 'PWATest',
+    lang: 'ja',
+    theme_color: '#ffffff',
+    background_color: '#ffffff'
+  },

ホーム画面に表示するアイコン画像はデフォルトだと/static/logo.pngを読みに行くので、正方形の画像を用意して置いておきましょう。

そうすると、下記のように、ホーム画面に設置すると、アイコンが表示され、タップするとスプラッシュ画面とともにアプリケーションが表示されます

まとめ

今回はPWAの基本となる3点の機能を紹介させていただきました。 他にも機能はあるので、興味のある方は GoogleのWebFundamentals等を見るといいかと思います。