如何使用 Vanilla JavaScript 构建 PWA
这是关于如何利用 Web Push API 和 cron-schedule 创建渐进式 Web 应用 (PWA) 的三部分系列文章的第一部分。在本文中,我们将介绍基础知识:前端、Web 应用清单和应用的 Service Worker 方面,我们将仅使用纯 JavaScript 来实现这一点。在这篇文章的最后,我们将得到一个可以缓存的 PWA,以便在离线时访问它。
我们正在建设什么
我的医生最近告诉我每天要吃 3 片药。回家的路上我告诉自己:“我是一名开发人员,我负责自动执行任务,让我们开发一款应用来帮助我吃药吧。”
我们将构建一个简单的渐进式 Web 应用程序 (PWA),它会提醒我每天吃药。
我们的应用将拥有一个由 Express.js 提供支持的 Web 服务器。Express 将向订阅推送通知的客户端推送通知。它还将为前端应用提供服务。
第一步:PWA
我们正在开发的应用程序必须在浏览器未打开时提醒我们吃药。所以我们需要一个渐进式 Web 应用程序。
准备好清单
构建 PWA 的第一步是使用此生成器生成清单。此工具将创建manifest.json
包含应用所有基本信息的文件。它还将创建一些图标,这些图标将在用户下载应用时显示在用户手机上。
只需将所有内容解压到我们项目根目录下的文件夹中,我们将该文件夹命名为public
。我决定将我的应用程序命名为 Temporas。
"name": "Temporas",
"short_name": "Temporas",
"theme_color": "#222831",
"background_color": "#ffad17",
"display": "standalone",
"Scope": "",
"start_url": "/index.html",
"icons": [
// A lot of icons
]
PWA 依赖于Service Workers。Service Workers 是一些小程序,它们在注册后会独立于其余 JavaScript 代码运行。Service Workers 无法直接与 DOM 交互,但可以向其余代码发送消息(我们将在本系列的第 2 部分中更详细地探讨这一点)。
现在让我们创建前端并注册我们的服务人员:
<!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>
// Registering our Service worker
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js', { scope: './' })
}
</script>
</head>
<body>
<div class="hero">
<h1>Temporas</h1>
<h2>Take your medicine my friend</h2>
<div id="status"></div>
<button id="unsubscribe">unsubscribe</button>
</div>
</body>
现在,我们距离拥有一个可安装的 Web 应用程序仅差一个文件。让我们创建我们的服务工作者:
const cacheName = 'Temporas';
// Cache all the files to make a PWA
self.addEventListener('install', e => {
e.waitUntil(
caches.open(cacheName).then(cache => {
// Our application only has two files here index.html and manifest.json
// but you can add more such as style.css as your app grows
return cache.addAll([
'./',
'./index.html',
'./manifest.json'
]);
})
);
});
// Our service worker will intercept all fetch requests
// and check if we have cached the file
// if so it will serve the cached file
self.addEventListener('fetch', event => {
event.respondWith(
caches.open(cacheName)
.then(cache => cache.match(event.request, { ignoreSearch: true }))
.then(response => {
return response || fetch(event.request);
})
);
});
我们有一个 PWA
设置 Express.js
如果您只是在浏览器中打开,PWA 将无法工作/public/index.html
。我们必须从 Web 服务器提供内容。
首先,让我们在命令行中进行设置。在根文件夹中运行:
$ npm init
$ npm install express body-parser
$ touch app.js
内部将字段package.json
替换scripts
为:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node app.js"
}
现在让我们填充我们的应用程序:
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const port = 3000;
// We want to use JSON to send post request to our application
app.use(bodyParser.json());
// We tell express to serve the folder public as static content
app.use(express.static('public'));
app.get('/public');
app.listen(port, () => console.log(`Listening on port ${port}!`));
现在您可以运行npm run start
。转到http://localhost:3000,关闭服务器。重新加载http://localhost:3000,应用程序看起来仍然在运行!您甚至可以关闭笔记本电脑并返回该端口上的网页。
我强烈建议您在开发新功能时禁用服务工作者的缓存机制。这可能会引起一些混乱。
如果您想了解有关设置 Express 服务器的更多信息,这里有一篇不错的文章。
检查你的 PWA
为了测试您的 PWA,我强烈建议您使用Lighthouse 扩展程序来查看一切是否正常。还请记住,在网络上部署您的应用时,需要通过 HTTPS 提供服务才能被视为 PWA 并可作为应用安装。
您可以在此Github 存储库中找到所有代码。