渐进式 Web 应用(或 PWA)是提供类似于原生应用体验的 Web 应用。有很多因素可以促成这一点。其中最重要的是应用能够在离线状态下运行。这是通过使用一种名为 Service Workers 的 Web 技术实现的。
本节将重点介绍如何为我们的应用添加离线体验。我们将使用一个名为 Workbox 的 Google 项目来实现这一点,该项目提供了一些工具,可以帮助更轻松地设置 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
如果您在浏览器中打开 http://localhost: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]
...
如你所见,我们现在生成了两个额外的文件: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
启动它。导航到 http://localhost:8080
并查看控制台。你应该在其中看到以下内容。
SW registered
现在来测试它。停止服务器并刷新页面。如果你的浏览器支持 Service Workers,那么你应该仍然看到你的应用程序。但是,它是由你的 Service Worker 提供的,而不是由服务器提供的。
你已经使用 Workbox 项目构建了一个离线应用程序。你已经开始了将你的 Web 应用程序转换为 PWA 的旅程。你现在可能想要考虑进一步发展。你可以在这里找到一个可以帮助你的资源:这里.