渐进式 Web 应用程序(简称 PWA)是提供类似原生应用程序体验的 Web 应用。有许多因素可以促成这一点。其中最重要的是应用在**离线**时也能运行的能力。这通过一种名为 Service Workers 的 Web 技术实现。
本节将重点介绍为我们的应用添加离线体验。我们将使用一个名为 Workbox 的谷歌项目来实现这一点,它提供了工具,有助于更轻松地为 Web 应用设置离线支持。
到目前为止,我们一直通过直接访问本地文件系统来查看输出。然而,通常情况下,真实用户通过网络访问 Web 应用;他们的浏览器会与一个**服务器**通信,该服务器将提供所需的资源(例如 .html
、.js
和 .css
文件)。
所以,让我们用一个功能更基础的服务器来测试当前体验如何。我们将使用 http-server 包:npm install http-server --save-dev
。我们还将修改 package.json
的 scripts
部分,添加一个 start
脚本。
package.json
{
...
"scripts": {
- "build": "webpack"
+ "build": "webpack",
+ "start": "http-server dist"
},
...
}
注意:webpack DevServer 默认写入内存。我们需要启用 devserverdevmiddleware.writeToDisk 选项,以便 http-server 能够从 ./dist
目录提供文件。
如果你之前没有这样做过,请运行命令 npm run build
来构建你的项目。然后运行命令 npm start
。这将产生以下输出
> 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
如果你在浏览器中打开 https://:8080
(即 http://127.0.0.1
),你应该会看到你的 webpack 应用程序从 dist
目录提供服务。如果你停止服务器并刷新,webpack 应用程序将不再可用。
这正是我们想要改变的。一旦我们完成这个模块,我们应该能够停止服务器,刷新页面,仍然可以看到我们的应用程序。
让我们添加 Workbox webpack 插件并调整 webpack.config.js
文件
npm install workbox-webpack-plugin --save-dev
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
+ const WorkboxPlugin = require('workbox-webpack-plugin');
module.exports = {
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
会发生什么
...
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]
...
如你所见,我们现在生成了 2 个额外文件: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 来启用它。我们将通过添加以下注册代码来实现
index.js
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
启动服务。导航到 https://:8080
并查看控制台。你应该会在其中看到
SW registered
现在来测试它。停止你的服务器并刷新页面。如果你的浏览器支持 Service Workers,那么你应该仍然可以看到你的应用程序。然而,它是由你的 Service Worker 提供服务,而**不是**由服务器提供。
你已经使用 Workbox 项目构建了一个离线应用。你已经开始了将你的 Web 应用转变为 PWA 的旅程。你现在可能想要考虑进一步的提升。一个很好的资源可以帮助你,请点击这里。