渐进式 Web 应用(PWA)
渐进式 Web 应用(PWA)
本指南基于输出管理指南中的代码示例展开。
渐进式 Web 应用(Progressive Web Application,PWA)是能够提供类似原生应用体验的 Web 应用。有很多因素可以促成这种体验,其中最重要的是应用能够离线运行。这是通过一种名为 Service Workers 的 Web 技术实现的。
本节将重点为我们的应用添加离线体验。我们将使用 Google 的名为 Workbox 的项目来实现这一目标,该项目提供的工具可以帮助我们更轻松地为 Web 应用设置离线支持。
当前无法离线工作
到目前为止,我们一直都是直接通过本地文件系统查看输出。但通常情况下,真实用户是通过网络访问 Web 应用的;他们的浏览器会与服务器通信,由服务器提供所需的资源(例如 .html、.js 和 .css 文件)。
因此,让我们使用一个功能更基础的服务器来测试当前的体验。我们使用 http-server 包:npm install http-server --save-dev。同时,我们还要修改 package.json 中的 scripts 部分,添加一个 start 脚本:
package.json
diff
{
...
"scripts": {
- "build": "webpack"
+ "build": "webpack",
+ "start": "http-server dist"
},
...
}
注意:webpack DevServer 默认写入内存。我们需要启用 devserverdevmiddleware.writeToDisk 选项,以便 http-server 能够从 ./dist 目录提供文件。
如果之前还没有构建过项目,请先运行 npm run build 构建项目,然后运行 npm start。执行后会得到类似下面的输出:
bash
> http-server dist
Starting up http-server, serving dist
Available on:
http://xx.x.x.x:8080
http://127.0.0.1:8080
http://xxx.xxx.x.x:8080
Hit CTRL-C to stop the server
如果你在浏览器中打开 http://localhost:8080(即 http://127.0.0.1),应该会看到 webpack 应用正在从 dist 目录提供服务。如果你停止服务器并刷新页面,webpack 应用将不再可用。
这正是我们要改变的地方。完成本模块的学习后,即使停止服务器并刷新页面,也应该仍然能够看到我们的应用。
添加 Workbox
让我们添加 Workbox webpack 插件,并调整 webpack.config.js 文件:
bash
npm install workbox-webpack-plugin --save-dev
webpack.config.js
diff
import path from "node:path";
import { fileURLToPath } from 'node:url';
import HtmlWebpackPlugin from "html-webpack-plugin";
+ import WorkboxPlugin from "workbox-webpack-plugin";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export default {
entry: {
app: './src/index.js',
print: './src/print.js',
},
plugins: [
new HtmlWebpackPlugin({
- title: 'Output Management',
+ title: 'Progressive Web Application',
}),
+ new WorkboxPlugin.GenerateSW({
+ // these options encourage the ServiceWorkers to get in there fast
+ // and not allow any straggling "old" SWs to hang around
+ clientsClaim: true,
+ skipWaiting: true,
+ }),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
完成上述配置后,让我们运行 npm run build,看看会发生什么:
bash
...
Asset Size Chunks Chunk Names
app.bundle.js 545 kB 0, 1 [emitted] [big] app
print.bundle.js 2.74 kB 1 [emitted] print
index.html 254 bytes [emitted]
precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js 268 bytes [emitted]
service-worker.js 1 kB [emitted]
...
如你所见,现在会额外生成两个文件:service-worker.js 和内容更详细的 precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js。service-worker.js 是 Service Worker 文件,而 precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js 是 service-worker.js 运行所需的文件。你自己生成的文件可能会有所不同,但目录中应该会有一个 service-worker.js 文件。
至此,我们已经成功生成了一个 Service Worker。接下来该做什么?
注册 Service Worker
让我们通过注册 Service Worker 来让它正式生效。我们将添加以下注册代码:
index.js
diff
import _ from 'lodash';
import printMe from './print.js';
+ if ('serviceWorker' in navigator) {
+ window.addEventListener('load', () => {
+ navigator.serviceWorker.register('/service-worker.js').then(registration => {
+ console.log('SW registered: ', registration);
+ }).catch(registrationError => {
+ console.log('SW registration failed: ', registrationError);
+ });
+ });
+ }
再次运行 npm run build,构建包含注册代码的应用版本,然后使用 npm start 提供服务。打开 http://localhost:8080 并查看控制台,你应该能在其中看到:
bash
SW registered
现在来测试一下。停止服务器并刷新页面。如果你的浏览器支持 Service Worker,你仍然应该能够看到你的应用。不过,此时它是由 Service Worker 提供的,而不是由服务器提供的。
结论
你已经使用 Workbox 项目构建了一个离线应用,并开启了将 Web 应用转变为 PWA 的旅程。现在,你或许想要进一步拓展。这里有一个很好的资源可以帮助你:https://web.dev/progressive-web-apps/。
帮助我们改进文档
发现翻译问题或内容错误?请告诉我们。
