PWA BuilderでPWA化してみてPWAを学ぶ
PWA BuilderというPWA化するためのToolを試してみた記録です。
ざっくりとPWAとは何なのかが分かる内容になっていると思います。
今回は以下のサンプルを利用しています。
Freelancer - One Page Theme - Start Bootstrap
PWA化したデモサイトはこちらです。
Freelancer - Start Bootstrap Theme
PWAとは
PWAはProgressive Web Appsのことです。
PWA Builderの説明によると、以下の内容を含んだものがPWAと言えると思います。
- Web App Manifestを使用してモバイル端末等からインストールおよび起動されたときの見た目や動作を制御している
- Service Workerを使用してオフライン対応がされている
マニフェストファイルを作成する
PWA Builderの手順に沿って説明します。
まずはGenerate Manifestでの手順です。
PWA Builderを使うと以下のマニフェストファイルが作成されます。
manifest.json
{ "dir": "ltr", "lang": "Japanese", "name": "Freelancer - Start Bootstrap Theme", "scope": "/", "display": "standalone", "start_url": "https://arched-photon-204013.firebaseapp.com/", "short_name": "Freelancer", "theme_color": "transparent", "description": "", "orientation": "any", "background_color": "transparent", "related_applications": [], "prefer_related_applications": false, "icons": [ { "src": "img/d2248ed4-ab6f-84da-fe68-5962b432d4ac.webPlatform.png", "sizes": "48x48", "type": "image/png" }, { "src": "img/b1d7d8f5-1b9b-a7e9-e644-ba9db81e4d93.webPlatform.png", "sizes": "1240x600", "type": "image/png" }, { "src": "img/4f8afd0d-e3e4-1f11-4f22-3bd7ebfb0c61.webPlatform.png", "sizes": "300x300", "type": "image/png" }, { "src": "img/9c2802bf-a937-d809-fd3a-52f1059a43d8.webPlatform.png", "sizes": "150x150", "type": "image/png" }, { "src": "img/fe805efb-f87e-ff12-eb44-86cc76225d06.webPlatform.png", "sizes": "88x88", "type": "image/png" }, { "src": "img/bd3ec8f1-9ef0-de1f-3d55-093be35a1b5b.webPlatform.png", "sizes": "24x24", "type": "image/png" }, { "src": "img/335ca134-e557-a127-dd7a-f1af5ee35285.webPlatform.png", "sizes": "50x50", "type": "image/png" }, { "src": "img/e19531de-b9a8-0cf7-cc34-0d91b68a0339.webPlatform.png", "sizes": "620x300", "type": "image/png" }, { "src": "img/01b4b12b-d6f8-5e7c-897b-642ae94809b2.webPlatform.png", "sizes": "192x192", "type": "image/png" }, { "src": "img/a220fe60-f154-a4b0-2645-7d962bdffd78.webPlatform.png", "sizes": "144x144", "type": "image/png" }, { "src": "img/f699c6fb-cd5b-58a0-6e9a-352f1520876c.webPlatform.png", "sizes": "96x96", "type": "image/png" }, { "src": "img/809fd415-acc1-e2b3-39fb-70e2e867e0e9.webPlatform.png", "sizes": "72x72", "type": "image/png" }, { "src": "img/233576f2-1bb0-e4cd-c0a3-bd0e4605f3c9.webPlatform.png", "sizes": "36x36", "type": "image/png" }, { "src": "img/c1007a03-b2e6-e063-b1a6-e809c502ee0d.webPlatform.png", "sizes": "1024x1024", "type": "image/png" }, { "src": "img/c84d6d5e-051e-1555-dca8-c80c1c2a3181.webPlatform.png", "sizes": "180x180", "type": "image/png" }, { "src": "img/df1a52c0-a9dd-8923-51c4-8fd1ab582afb.webPlatform.png", "sizes": "152x152", "type": "image/png" }, { "src": "img/19a904d2-30d1-720c-52b6-c44bd97cf378.webPlatform.png", "sizes": "120x120", "type": "image/png" }, { "src": "img/3235cb0f-c9a5-2a68-d389-9168a8afe050.webPlatform.png", "sizes": "76x76", "type": "image/png" }, { "src": "img/android-launchericon-512-512.png", "sizes": "512x512", "type": "image/png" } ] }
注目する設定としては、display
プロパティの指定でネイティブアプリを起動するような形でWebアプリを起動することができます。
pwabuilder.comからマニフェストファイルを作成できる対象は公開されているサイトになります。
今回はFirebase上にデプロイしてサイトを公開しています。
Service WorkerのJavaScriptファイルを作成する
Build Service Workerでの手順です。
Cache-first networkを選択します。
以下のファイルが作成されます。
pwabuilder-sw-register.js
//This is the service worker with the Cache-first network //Add this below content to your HTML page, or add the js file to your page at the very top to register service worker if (navigator.serviceWorker.controller) { console.log('[PWA Builder] active service worker found, no need to register') } else { //Register the ServiceWorker navigator.serviceWorker.register('pwabuilder-sw.js', { scope: './' }).then(function(reg) { console.log('Service worker has been registered for scope:'+ reg.scope); }); }
index.htmlで読み込むJavaScriptファイルになります。
ServiceWorkerを登録するために利用します。
pwabuilder-sw.js
//This is the service worker with the Cache-first network var CACHE = 'pwabuilder-precache'; var precacheFiles = [ /* Add an array of files to precache for your app */ 'vendor/bootstrap/css/bootstrap.min.css', 'vendor/font-awesome/css/font-awesome.min.css', 'vendor/magnific-popup/magnific-popup.css', 'css/freelancer.min.css', 'img/profile.png', 'img/portfolio/cabin.png', 'img/portfolio/cake.png', 'img/portfolio/circus.png', 'img/portfolio/game.png', 'img/portfolio/safe.png', 'img/portfolio/submarine.png', 'vendor/jquery/jquery.min.js', 'vendor/bootstrap/js/bootstrap.bundle.min.js', 'vendor/jquery-easing/jquery.easing.min.js', 'vendor/magnific-popup/jquery.magnific-popup.min.js', 'js/jqBootstrapValidation.js', 'js/contact_me.js', 'js/freelancer.min.js', 'manup.min.js' ]; //Install stage sets up the cache-array to configure pre-cache content self.addEventListener('install', function(evt) { console.log('The service worker is being installed.'); evt.waitUntil(precache().then(function() { console.log('[ServiceWorker] Skip waiting on install'); return self.skipWaiting(); }) ); }); //allow sw to control of current page self.addEventListener('activate', function(event) { console.log('[ServiceWorker] Claiming clients for current page'); return self.clients.claim(); }); self.addEventListener('fetch', function(evt) { console.log('The service worker is serving the asset.'+ evt.request.url); if(!evt.request.url.includes('https')){ return; } evt.respondWith(fromCache(evt.request).catch(fromServer(evt.request))); evt.waitUntil(update(evt.request)); }); function precache() { return caches.open(CACHE).then(function (cache) { return cache.addAll(precacheFiles); }); } function fromCache(request) { //we pull files from the cache first thing so we can show them fast return caches.open(CACHE).then(function (cache) { return cache.match(request).then(function (matching) { return matching || Promise.reject('no-match'); }); }); } function update(request) { //this is where we call the server to get the newest version of the //file to use the next time we show view return caches.open(CACHE).then(function (cache) { return fetch(request).then(function (response) { return cache.put(request, response); }); }); } function fromServer(request){ //this is the fallback if it is not in the cache to go to the server and get it return fetch(request).then(function(response){ return response}) }
ServiceWorkerによるキャッシュを行うJavaScriptファイルになります。
precacheFilesという配列にキャッシュを行うファイルを手動で記述する必要があります。
PWAとして構築する
WebでDownloadを選択します。
Web App Manifestの設定
<link rel="manifest" href="manifest.json"></link>
- Web App Manifestのpolyfillを適用します。
<script src="manup.js"></script>
ファイルの場所
https://github.com/boyofgreen/manUp.js/
Service Workerの設定
- pwabuilder-sw-register.jsを読み込みます。
<script src="pwabuilder-sw-register.js"></script>
結果
Android端末にインストールしてみました。
オフライン時でも表示ができています。