PWA(Progressive Web Apps)ãšã¯ãWebãµã€ãã«ãã€ãã£ãã¢ããªã®ãããªæ©èœãæããããã®ã§ãããã©ãŠã¶ããã€ã³ã¹ããŒã«ã§ããŠããªãã©ã€ã³ã§ãåäœãããããšå¯èœã«ãªããŸãããŸããç¹å¥ãªããŒã«ã¯å¿ èŠãªããHTMLãšJavaScriptã§äœæã§ããŸããä»åã¯ãPWAãšã¯ã©ã®ãããªä»çµã¿ã§æ§æãããã®ã確èªããŠã¿ãŸãããã
PWAã®æ©èœã«ã€ããŠ
Webãµã€ããPWAã«å¯Ÿå¿ãããšã©ããªè¯ãããšãããã®ã§ããããããŸãããã€ãã£ãã¢ããªã®ããã«ãã€ã³ã¹ããŒã«ã§ãããšããã®ã倧ããªã¡ãªããã§ããã¹ããŒããã©ã³ã§ããã°ãããŒã ç»é¢ãã«ã¢ããªãé 眮ã§ããŸããPCã§ãã¢ããªã±ãŒã·ã§ã³ãã©ã«ãã«ã·ã§ãŒãã«ãããäœæãããã®ã§ãèµ·åã容æã«ãªããŸããäŸãã°ã以äžã¯Chromeã§TwitterãéããŠã€ã³ã¹ããŒã«ãããšããã§ãããã€ãã£ãã¢ããªã®ããã«ã¢ã€ã³ã³ããèµ·åã§ããŠãã¢ãã¬ã¹ããŒããªãããã«ã¢ããªãå®è¡ã§ããã®ãã¡ãªããã§ãã
ãããŠãService Workerã®ä»çµã¿ãå©çšããããšã§ãã³ã³ãã³ããããŒã«ã«ã«ãã£ãã·ã¥ããŠããŠãŒã¶ãŒããªãã©ã€ã³ã®ç¶æ ã§ãããµã€ããå©çšããããšãã§ããããã«ãªããŸãã
ç¹ã«ã¹ããŒããã©ã³ã§ã¯ãç§»åæãªã©äžæçã«éä¿¡ç¶æ ãæªããªãããªãã©ã€ã³ã«ãªã£ãŠããŸãããšããããããŸããæ¥åããŒã«ãªã©ãWebã¢ããªãšããŠæäŸãããŠããå ŽåãéããŠäœ¿ãããšãããéä¿¡ç¶æ ãæªããŠæ å ±ãèŠãããªããèšç®ããŒã«ã䜿ããªãã£ããšããã®ã¯ããšãŠãäžäŸ¿ã§ããPWAã«å¯Ÿå¿ããŠããã°ãããããåé¡ããªããªããŸãã
ãŸããWebããã·ã¥éç¥ãå©çšã§ããŸããOSã®éç¥æ©èœãå©çšããŠããµã€ãã®æŽæ°æ å ±ãéç¥ã§ããŸãããã®ããã«ãPWAåããããšã§ãããããã®ã¡ãªããã享åã§ããããã«ãªããŸãã
PWAåã®ããã«å¿ èŠãªäœæ¥
ãŸããWebãµã€ããã€ã³ã¹ããŒã«å¯èœã«ããããã®äœæ¥ã確èªããŠã¿ãŸããããæäœéå¿ èŠãªã®ã¯æ¬¡ã®åç¹ã§ãã
- (1) Webã¢ããªã®ã¢ã€ã³ã³ãçšæãã
- (2) ãããã§ã¹ããã¡ã€ã«ãçšæãã
- (3) Service Worker APIã«å¯Ÿå¿ãã
- (4) HTTPS察å¿ã®ãµã€ãã«é 眮ãã
(1)ã¢ã€ã³ã³ãçšæããã
äžã€ãã€ç¢ºèªããŠãããŸãããããŸããæåã®(1)ã§ãããã€ã³ã¹ããŒã«ã§ããã¢ããªã«ããããã«ã¯ãã¢ããªã®ã¢ã€ã³ã³ãçšæããå¿ èŠããããŸããã¢ã€ã³ã³ã¯ãç°ãªããµã€ãºã®PNGç»åãã¡ã€ã«ãçšæããŸããã©ã®ãµã€ãºã®ãã®ãçšæãããã¯ãäž»ã«ã©ã®ç«¯æ«ã«å¯Ÿå¿ããããã«ãã£ãŠç°ãªããŸãã倧ã¯å°ãå Œãããšããç¹ããã512x512ãã¯ã»ã«ãªã©ãµã€ãºã®å€§ããªç»åããããã¯ãSVG圢åŒã®ç»åãäœæããŠããããå ã«ãžã§ãã¬ãŒã¿ãŒãªã©ã§ã¢ã€ã³ã³ãèªåäœæãããšæ¥œã§ãããããã®ç¹ã¯åŸè¿°ããŸãã
(2)ãããã§ã¹ããã¡ã€ã«ãçšæããã
ã¢ã€ã³ã³ãçšæãããããããã§ã¹ããã¡ã€ã«ãäœæããŸãããããããã§ã¹ããã¡ã€ã«ã¯ãWebã¢ããªã®æ å ±ãèšè¿°ããJSON圢åŒã®ãã¡ã€ã«ã§ããæ¬¡ã®ãããªãããã§ã¹ããã¡ã€ã«ãäœæããŠãHTMLãããªã³ã¯ããŸãã
{
"name": "ãã¹ãã¢ã㪠- TestApp",
"short_name": "TestApp",
"description": "PWAã®ãã¹ãã¢ããªã§ãã",
"icons": [],
"start_url": "/index.html",
"display": "standalone",
"theme_color": "#0000FF",
"background_color": "#0000FF"
}
äžèšã®ãã¡ã€ã«ããmanifest.jsonããšããååã§ä¿åããŸãããããããŠãHTMLãã¡ã€ã«ãããªã³ã¯ããŸãã
<link rel="manifest" href="manifest.json">
ããã§ã¯ãããã§å®éã«ã¢ã€ã³ã³ãäœæãããããã§ã¹ããèªåçæããŠã¿ãŸãããããã®ããã«ãNode.jsãå©çšããŸããNode.jsãã€ã³ã¹ããŒã«ãããŠããªããã°ããã¡ãããã€ã³ã¹ããŒã«ããŠãã ããã
ã³ãã³ãã©ã€ã³(Windowsã§ã¯PowerShellãmacOSã§ã¯ã¿ãŒããã«.app)ãèµ·åããŠã以äžã®ã³ãã³ããå®è¡ããŸããããããã¯ãpwa-asset-generatorãã€ã³ã¹ããŒã«ãããã®ã§ãã
$ npm install -g pwa-asset-generator
ãããŠãããã§ã¯ãlogo.svgãšãããã¡ã€ã«ãå ã«ã¢ã€ã³ã³ãçæããŸããããäžèšã®ãmanifest.jsonãããã³ãããããªã³ã¯ããHTMLãã¡ã€ã«ãindex.htmlããçšæããäžã§ãäžèšã®ã³ãã³ããå®è¡ããŸãã
$ pwa-asset-generator logo.svg icons -m manifest.json -i index.html
ãããšãiconsãšãããã©ã«ãã«ãããããªãµã€ãºã®ã¢ã€ã³ã³ãèªåçæãããŸãããããŠãèªåçã«ãããã§ã¹ããã¡ã€ã«ãšHTMLãã¡ã€ã«ã«ãªãµã€ãºããã¢ã€ã³ã³ããªã³ã¯ãããŸãã
(3)Service Workerã«å¯Ÿå¿ããã
Service Workerãšããã®ã¯ãããã²ãŒã·ã§ã³ããªãœãŒã¹ãžã®ãªã¯ãšã¹ããå¶åŸ¡ããæ©èœã®ããšã§ãããããã¯ãŒã¯ããååŸãããªãœãŒã¹ããã£ãã·ã¥ããããã«ãããããªãã©ã€ã³ã®æã«ãã£ãã·ã¥ãããªãœãŒã¹ãè¿ããããšãã¢ããªã®æ¯ãèãã倿Žã§ããŸããããããæ¯ãèããJavaScriptã§èšè¿°ããŸãã
å ã»ã©ããããã§ã¹ãããªã³ã¯ããHTMLãã¡ã€ã«ãindex.htmlãã«æ¬¡ã®ãããªJavaScriptã远å ããŸãããã以äžã®ããã«èšè¿°ããããšã§ãService Workerã§ãããservice-worker.jsããç»é²ããŸãã
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js').then(reg => {
console.log('ãµãŒãã¹ã¯ãŒã«ãŒãç»é²ããŸãã', reg);
}).catch(err => {
console.log('ç»é²å€±æ', err);
});
}
</script>
ãããŠãå®éã®Service Workerã§ãããservice-worker.jsãã¯æ¬¡ã®ãããªãã¡ã€ã«ãçšæããŸãã
// ãã£ãã·ã¥ããããã¡ã€ã«ã®äžèЧãæå® --- (*1)
const cacheFiles = ['index.html', 'logo.svg'];
const cacheName = 'v1';
// ã€ã³ã¹ããŒã«æã«å®è¡ãããã€ãã³ã --- (*2)
self.addEventListener('install', event => {
// ãã£ãã·ã¥ããããã¡ã€ã«ãæå®
caches.open(cacheName).then(cache => cache.addAll(cacheFiles));
});
// ã€ã³ã¹ããŒã«åŸã«å®è¡ãããã€ãã³ã
self.addEventListener('activate', event => {
// å¿
èŠã«å¿ããŠå€ããã£ãã·ã¥ã®åé€åŠçãªã©ãè¡ã
});
// fetchã€ãã³ã
self.addEventListener('fetch', event => {
// ãã£ãã·ã¥ãããã°ãããè¿ã --- (*3)
event.respondWith(
caches.match(event.request).then(function(resp) {
return resp || fetch(event.request).then(function(response) {
let responseClone = response.clone();
caches.open(cacheName).then(function(cache) {
cache.put(event.request, responseClone);
});
return response;
});
}).catch(function() {
return caches.match('logo.svg');
}));
});
ããã°ã©ã ã確èªããŠã¿ãŸãããã(ïŒ1)ã§ã¯ããã©ãŠã¶ã«ãã£ãã·ã¥ããããã¡ã€ã«ã®äžèЧãæå®ããŸãã(ïŒ2)ã®éšåã§ãã£ãã·ã¥ããããã¡ã€ã«ãå®éã«ç»é²ããŸãããããŠã(ïŒ3)ã§ã¯å®éã«ãªãœãŒã¹ã®èŠæ±ããã£ããšãã«ãäœãè¡ãã®ããæå®ãããfetchã€ãã³ããèšè¿°ããŸããããã§ã¯ã(ïŒ2)ã§ãã©ãŠã¶ã«ãã£ãã·ã¥ãããã¡ã€ã«ãè¿ãããã«ããŸãã
ãããŸã§ã®index.htmlãã¡ã€ã«ã¯ä»¥äžã®ããã«ãªããŸãã
<html>
<head>
<meta charset="utf-8">
<title>TestApp</title>
<link rel="manifest" href="manifest.json">
<!-- 以äžã¯ãèªåã§è¿œå ãããã³ãŒã -->
<link rel="apple-touch-icon" href="icons/apple-icon-180.png">
<!-- çç¥... -->
</head>
<body>
<h1>TestApp</h1>
<img src="logo.svg">
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js').then(reg => {
console.log('ãµãŒãã¹ã¯ãŒã«ãŒãç»é²ããŸãã', reg);
}).catch(err => {
console.log('ç»é²å€±æ', err);
});
}
</script>
</body></html>
(4)ãµã€ãã«é 眮ããã
æåŸã«ããããŸã§ã§çšæãããã¡ã€ã«äžåŒãWebãµã€ãã«é 眮ããŸããããã¡ã€ã³ãã¡ã€ã«ã®ãindex.htmlãããããŠããããã§ã¹ããmanifest.jsonããService Workerã®æ¬äœãservice-worker.jsããšã¢ã€ã³ã³ã§ãããªãããããŸã§ã®ãã¡ã€ã«äžåŒã¯ããã¡ãããããŠã³ããŒãã§ããŸãã
ãããŠããã¡ã€ã«äžåŒããã©ãŠã¶ã§èŠãããããã«ããã«ã¯ãHTTPSã§ã¢ã¯ã»ã¹ã§ããWebãµã€ãããããã¯ãlocalhostã«é 眮ããå¿ èŠããããŸããããã§ã¯ããã¹ãçšã«ãlocalhostãå©çšããŠã¿ãŸãããã
ã³ãã³ãã©ã€ã³ãéããŠä»¥äžã®ã³ãã³ããå®è¡ããŸããããããã¯ãNode.jsã®ç°¡æWebãµãŒããŒãã€ã³ã¹ããŒã«ãããã®ã§ãã
npm install -g serve
ãããŠãçšæãããã¡ã€ã«äžåŒã®ãããã£ã¬ã¯ããªã§ã§ä»¥äžã®ã³ãã³ããå®è¡ããŸãã
serve .
ãããšãWebãµãŒããŒãèµ·åããã®ã§ãç»é¢ã«è¡šç€ºãããURLã«ã¢ã¯ã»ã¹ããŸããããããã©ã«ãã§ã¯ãhttp://localhost:3000 ã§ãããã©ãŠã¶ã§ãã®ã¢ãã¬ã¹ã«ã¢ã¯ã»ã¹ããŸãããããããšããµã€ãã衚瀺ãããŸãã
ãªããGoogle Chromeã§ã¯ããŒãžãå³ã¯ãªãã¯ããŠããããã¢ããã¡ãã¥ãŒãããæ€èšŒããã¯ãªãã¯ãããšãéçºè ããŒã«ã衚瀺ãããŸããç¹ã«ãã¢ããªã±ãŒã·ã§ã³ãã®ã¿ããéããService Workerã®é ç®ã確èªããŠã¿ãŸããããæ£ããåããŠããªããããªããç»é²è§£é€ãã®ãªã³ã¯ãã¯ãªãã¯ãããšãService Workerãåæåã§ããŸãã
ãããŠãæ£ãããµã€ãã衚瀺ãããããã³ãã³ãã©ã€ã³ã«æ»ã£ãŠ[Ctrl]+[C]ãã¯ãªãã¯ããŸãããããããšãµãŒããŒãçµäºããŸãããµãŒããŒãçµäºãããåŸã§ããã©ãŠã¶ã«æ»ãããªããŒããã¿ã³ãæŒããŠã¿ãŸãããããµãŒããŒãèµ·åããŠããªãç¶æ ã§ããæ£ããããŒãžã衚瀺ãããã®ã確èªã§ããã§ãããã
次ã«ãã€ã³ã¹ããŒã«ã詊ããŠã¿ãŸããããæ®å¿µãªããlocalhostã§ã€ã³ã¹ããŒã«ã®æ©èœã詊ãããšã¯ã§ããŸãããHTTPSæ¥ç¶ãå¯èœãªWebãµã€ãã«ã¢ããããŒãããå¿ èŠããããŸãã
ãã¡ã€ã«äžåŒããHTTPSã®ãµã€ãã«é 眮ãããšãPWAãšããŠã€ã³ã¹ããŒã«ã§ããããã«ãªããŸããããã§ã¯ããã¡ãã®ãã¢ãµã€ãã«é 眮ããŠã¿ãŸãããGoogle ChromeãMicrosoft Edgeã§ã¯ã¡ãã¥ãŒã®ãâŠãããã¢ããªãã€ã³ã¹ããŒã«ã§ããŸãã
ãŸãšã
以äžãä»åã¯ãã©ãŠã¶ããæè»œã«ã€ã³ã¹ããŒã«ã§ããã¢ããªã®PWAãäœã£ãŠã¿ãŸããããããŸã§éããHTMLãšJavaScriptã䜿ã£ãŠäœæã§ããŸããä»å玹ä»ãããã€ã³ãããæŒãããã°ãããã»ã©è€éãªæé ãå¿ èŠãªããã§ã¯ãããŸããããã®ãããæ¢åã®Webãµã€ããPWA察å¿ããã®ããããã»ã©é£ãããããŸãããPWAã«ããããšã§ãå©äŸ¿æ§ãé£èºçã«åäžããŸããæ¬çš¿ãPWA察å¿ã®è¶³ãããã«ãªãã°å¹žãã§ãã
èªç±åããã°ã©ããŒããããã¯ãã©ã«ãŠãããã°ã©ãã³ã°ã®æ¥œãããäŒããæŽ»åãããŠããã代衚äœã«ãæ¥æ¬èªããã°ã©ãã³ã°èšèªããªã§ããã ãããã¹ã鳿¥œããµã¯ã©ããªã©ã2001幎ãªã³ã©ã€ã³ãœãã倧è³å ¥è³ã2004幎床æªèžãŠãŒã¹ ã¹ãŒããŒã¯ãªãšãŒã¿èªå®ã2010幎 OSSè²¢ç®è ç« åè³ãæè¡æžãå€ãå·çããŠãããçŽè¿ã§ã¯ããã·ãŽããã¯ãã©ã PythonèªååŠçã®æç§æž(ãã€ããåºç)ããããã«äœ¿ãã!æ¥åã§å®è·µã§ãã! Pythonã«ããAIã»æ©æ¢°åŠç¿ã»æ·±å±€åŠç¿ã¢ããªã®ã€ããæ¹ TensorFlow2察å¿(ãœã·ã )ãããã³ã¬ã§ãã£ããåŠã¶Python(ãã€ããåºç)ããªã©ã






