วิธีการทำ Progressive Web Application ด้วย Vanila JavaScript อย่างง่าย
-|public
|- index.html
|- manifest.json
|- service-worker.js
|- icon.png
-|index.js
{
"name": "Thnovice",
"short_name": "Thnovice",
"theme_color": "#222831",
"background_color": "#ffad17",
"display": "standalone",
"Scope": "",
"start_url": "/index.html",
"icons": [
{
"src" : "/icon.png",
"sizes": "196x196",
"type": "image/png"
}
]
}
มีสามส่วน
const cacheName = 'Thnovice-cache';
self.addEventListener('install', e => {
e.waitUntil(
caches.open(cacheName).then(cache => {
return cache.addAll([
'./',
'./index.html',
'./manifest.json'
]);
})
);
});
let deferredPrompt;
self.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
addBtn.style.display = 'block';
addBtn.addEventListener('click', (e) => {
addBtn.style.display = 'none';
deferredPrompt.prompt();
deferredPrompt.userChoice.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
});
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.open(cacheName)
.then(cache => cache.match(event.request, { ignoreSearch: true }))
.then(response => {
return response || fetch(event.request);
})
);
});
const cacheName = 'Thnovice-cache';
self.addEventListener('install', e => {
e.waitUntil(
caches.open(cacheName).then(cache => {
return cache.addAll([
'./',
'./index.html',
'./manifest.json'
]);
})
);
});
let deferredPrompt;
self.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
addBtn.style.display = 'block';
addBtn.addEventListener('click', (e) => {
addBtn.style.display = 'none';
deferredPrompt.prompt();
deferredPrompt.userChoice.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
});
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.open(cacheName)
.then(cache => cache.match(event.request, { ignoreSearch: true }))
.then(response => {
return response || fetch(event.request);
})
);
});
....
<link rel='manifest' href='./manifest.json'>
<script>
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('./service-worker.js', { scope: './' })
}
</script>
....
....
....
<!DOCTYPE html>
<head>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<meta name="theme-color" content="#222831">
<link rel='manifest' href='./manifest.json'>
<script>
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('./service-worker.js', { scope: './' })
}
</script>
</head>
<body>
<div>
<h1>Hello PWA</h1>
</div>
</body>
$ yarn init
$ yarn add express body-parser
$ touch index.js
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const port = 3000;
app.use(bodyParser.json());
app.use(express.static('public'));
app.get('/public');
app.listen(port, () => console.log(`Listening on port ${port}!`));
Start Service
$ node index.js