渐进式 Web 应用

渐进式 Web 应用(或 PWA)是提供类似于原生应用体验的 Web 应用。有很多因素可以促成这一点。其中最重要的是应用能够在离线状态下运行。这是通过使用一种名为 Service Workers 的 Web 技术实现的。

本节将重点介绍如何为我们的应用添加离线体验。我们将使用一个名为 Workbox 的 Google 项目来实现这一点,该项目提供了一些工具,可以帮助更轻松地设置 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

如果您在浏览器中打开 http://localhost: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]
...

如你所见,我们现在生成了两个额外的文件: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 启动它。导航到 http://localhost:8080 并查看控制台。你应该在其中看到以下内容。

SW registered

现在来测试它。停止服务器并刷新页面。如果你的浏览器支持 Service Workers,那么你应该仍然看到你的应用程序。但是,它是由你的 Service Worker 提供的,而不是由服务器提供的。

结论

你已经使用 Workbox 项目构建了一个离线应用程序。你已经开始了将你的 Web 应用程序转换为 PWA 的旅程。你现在可能想要考虑进一步发展。你可以在这里找到一个可以帮助你的资源:这里.

5 位贡献者

johnnyreillychenxsanEugeneHlushkobenschacaholzner