渐进式 Web 应用

渐进式 Web 应用程序(简称 PWA)是提供类似原生应用程序体验的 Web 应用。有许多因素可以促成这一点。其中最重要的是应用在**离线**时也能运行的能力。这通过一种名为 Service Workers 的 Web 技术实现。

本节将重点介绍为我们的应用添加离线体验。我们将使用一个名为 Workbox 的谷歌项目来实现这一点,它提供了工具,有助于更轻松地为 Web 应用设置离线支持。

我们现在无法离线工作

到目前为止,我们一直通过直接访问本地文件系统来查看输出。然而,通常情况下,真实用户通过网络访问 Web 应用;他们的浏览器会与一个**服务器**通信,该服务器将提供所需的资源(例如 .html.js.css 文件)。

所以,让我们用一个功能更基础的服务器来测试当前体验如何。我们将使用 http-server 包:npm install http-server --save-dev。我们还将修改 package.jsonscripts 部分,添加一个 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

让我们添加 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.jsservice-worker.js 是 Service Worker 文件,而 precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.jsservice-worker.js 运行所需的文件。你生成的文件可能会有所不同;但你应该会有一个 service-worker.js 文件。

现在我们已经成功生成了一个 Service Worker。接下来是什么?

注册我们的 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 的旅程。你现在可能想要考虑进一步的提升。一个很好的资源可以帮助你,请点击这里

5 贡献者

johnnyreillychenxsanEugeneHlushkobenschacaholzner