gracetory’s blog

東池袋にある合同会社グレストリのエンジニアブログです

PWAはじめの一歩

f:id:grnishi:20200324012639p:plain

はじめに

オリンピックが延期されたけど、飛行機もホテルもキャンセルせずに札幌に行って遊ぼうと考えていたが、予想通りコロナが猛威を奮い続けているのでやっぱりキャンセルするgrnishiです。

2020年は無かった事にして、また来年2020年やりませんか? 年も取らなかった事にして、学校ももう1年。現実的に、大学の単位とかどうするんだろう。

本題

さて、タイトル「PWAはじめの一歩」として、さくっとやっていきます。

まずPWAとはProgressive Web Appsの事で、詳しい説明は下記に譲ります。

developer.mozilla.org

developers.google.com

必要なもの

  • エントリポイント(例えばindex.html)
  • Service Worker(例えばservice_worker.js)
  • 設定ファイル(例えばmanifest.json)

以上です。

厳密にはservice workerは無くてもいいのですが、どうせ使うので最初から。

とりあえず必要なものを用意する

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="manifest" href="manifest.json">
    <title>Sample</title>
    <script>
      function response() {
        var target = document.getElementById("target");
        var now = new Date();
        var hour = now.getHours();
        var minute = now.getMinutes();
        var second = now.getSeconds();
        target.innterHTML = hour + "時" + minute + "分" + second + "秒";
      }
    </script>
  </head>
  <body>
    <div id="app">
        <p id="target"></p>
        <button onClick="response();">今何時?</button>
     </div>
    <script>
      if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('service_worker.js').then(function(registration) {
          console.log('ServiceWorker registration successful with scope: ', registration.scope);
        }).catch(function(err) {
          console.log('ServiceWorker registration failed: ', err);
        });
      }
    </script>
  </body>
</html>

ボタンを押したら今何時か教えてくれるだけのシンプルなものをとりあえず。

<link rel="manifest" href="manifest.json">

ここでmanifest.jsonを指定します。

    <script>
      if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('service_worker.js').then(function(registration) {
          console.log('ServiceWorker registration successful with scope: ', registration.scope);
        }).catch(function(err) {
          console.log('ServiceWorker registration failed: ', err);
        });
      }
    </script>

ここでServiceWorkerの登録を行います。非対応ブラウザの場合は勝手に無視してくれるので気軽に。

var CACHE_NAME = "sample";
var CACHE_URL = [
    '/example.com/sample/',
];


self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(CACHE_NAME).then(function(cache) {
      return cache.addAll(CACHE_URL);
    })
  );
});

self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys().then(keys => Promise.all(
      keys.map(key => {
        if (!CACHE_NAME.includes(key)) {
          return caches.delete(key);
        }
      })
    )).then(() => {
      console.log(CACHE_NAME + "activated");
    })
  );
});

addEventListenerでinstall時の挙動のみ記述しています。ドメインは適宜書き換えてください。

{
  "short_name": "smpl",
  "name": "sample app",
  "display": "standalone",
  "start_url": "index.html"
}

manifest.jsonの項目

フィールド
name アプリ名
short_name 短いアプリ名。ホーム画面に表示される名前
lang 言語
start_url 起動時のURL
display 表示モード。fullscreen, standalone, minimal-ui, browserから選択。
background_color 背景色。
description 一般的な説明
dir 各メンバーの主なテキストの書字方向。日本ではなじみが無いですね。rtlは右から左。ltrは左から右。
orientation 画面の向き。any,natural,landscape,landscape-primary,landscape-secondary,portrait,portrait-primary,portrait-secondaryのいずれか
icons アプリアイコン。src,sizes,type,purposeを含む事ができます。
theme_color アプリケーションのテーマ色
scope ナビゲーションの範囲
related_applications 関連するネイティブアプリ。platform,url,idを含む事ができます。

適当なサーバにアップロードする

どこでも良いのですが、httpsが必須なのでGitHub Pagesが人気みたいです。

pages.github.com

実機で確認する

とりあえず該当のページを開いてみる。

f:id:grnishi:20200407190550p:plain

ホーム画面に追加する。

f:id:grnishi:20200407190721p:plain

とりあえずこのまま追加。

f:id:grnishi:20200407190757p:plain

ホーム画面に追加されました。

f:id:grnishi:20200407190810p:plain

起動してみると、ブラウザっぽく見えますが、アドレスバーがありません。PWA化できました。

f:id:grnishi:20200407190842p:plain

ボタンを押してもきちんと動作します。

f:id:grnishi:20200407190905p:plain

ページを遷移してみる

index2.htmlの遷移を作ってみる。結果としては特に問題無い。

f:id:grnishi:20200407190949p:plain f:id:grnishi:20200407191004p:plain

オフラインで使ってみる。

問題無し

f:id:grnishi:20200407191342p:plain

その他には

PUSH通知、Bluetooth制御、カメラ、DeviceMotion、位置情報、などなどアプリでしか出来なかった事もPWAで実装可能となっています。

他にもPWAを標準でサポートしているIonicフレームワーク、ServiceWorkerをかんたんにしてくれるWorkbox  |  Google DevelopersなどPWAを取り巻く環境も整備されてきております。

またGoogle I/Oで発表された通り、今後もどんどん拡張されていきます。Safariがどうなるかはわかりませんが。

さいごに

PWAはじめの一歩としてつらつらと試してみました。

社内用のちょっとしたツールなど、アプリでやるとちょっと面倒だなと思う事も多いと思います。

そんな時はPWAが有効です。

どこまでアプリっぽく作り込んでいくのか?という部分はありますが、とりあえずで良ければ簡単にアプリっぽくは作れます。

やはりストアを通さないという事は大きなアドバンテージなのかなと思いました。

次回はPWA次の一歩について記事にしたいと思います。いつかきっと。