Vue Cli 3如何使用官方PWA插件(Service Worker)

Vue Cli 3 how to use the official PWA plugin ( Service Worker )

在我的第一个 vue 项目中尝试使用官方 PWA 插件 (https://github.com/yyx990803/register-service-worker)。 我的具体问题:捕获注册的服务人员并将其用于任何事情。 github 自述文件显示了生成的确切文件,并且似乎没有关于如何在实例化后使用此服务工作者的文档为零(我是否捕获注册实例?如果是,如何?)

我发现了这个问题:https://github.com/vuejs/vue-cli/issues/1481 并且我提供了一个更好的地方来讨论这个问题,因为我还没有找到任何示例代码或关于如何使用它的清晰文档。

如果有人有一些示例代码,请分享。 Vue 和新的 cli 是令人难以置信的工具,记录这样的事情是提高平台采用率的必要步骤

正如已经指出的那样,它更像是一个 "service workers" 问题而不是 "vue cli" 问题。 首先,为了确保我们在同一页面上,registerServiceWorker.js 的样板内容应该是这样的(vue cli 3,官方 pwa 插件):

import { register } from 'register-service-worker'

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready () {
      console.log(
        'App is being served from cache by a service worker.\n'
      )
    },
    cached () {
      console.log('Content has been cached for offline use.')
    },
    updated () {
      console.log('New content is available; please refresh.')
    },
    offline () {
      console.log('No internet connection found. App is running in offline mode.')
    },
    error (error) {
      console.error('Error during service worker registration:', error)
    }
  })
}

如果您没有更改 .env 文件中的 BASE_URL 变量,那么它应该对应于您的 vue 应用程序的根目录。您必须在 public 文件夹中创建一个名为 service-worker.js 的文件(以便将其复制到您的输出中构建目录)。

现在,重要的是要了解 registerServiceWorker.js 文件中的所有代码都是注册一个 service worker 并提供一些挂钩到它的 lifecycle.这些通常用于调试目的,而不是实际对服务工作者进行编程。您可以通过注意到 registerServiceWorker.js 文件将被捆绑到 app.js 文件和 运行 在主线程中。

vue-cli 3 官方 PWA 插件基于 Google 的工作箱,因此要使用 service worker,您必须先在根目录下创建一个名为 vue.config.js 的文件并在其中复制以下代码:

// vue.config.js
module.exports = {
    // ...other vue-cli plugin options...
    pwa: {
        // configure the workbox plugin
        workboxPluginMode: 'InjectManifest',
        workboxOptions: {
            // swSrc is required in InjectManifest mode.
            swSrc: 'public/service-worker.js',
            // ...other Workbox options...
        }
    }
}

如果您已经创建了一个 vue.config.js 文件,那么您只需将 pwa 属性添加到配置对象。这些设置将允许您创建位于 public/service-worker.js 的自定义服务工作者,并让工作箱在其中注入一些代码:预缓存清单。它是一个 .js 文件,其中对已编译静态资产的引用列表存储在通常名为 self.__precacheManifest 的变量中。您必须在生产模式下构建您的应用程序,以确保是这种情况。

因为它是在生产模式下构建时由 workbox 自动生成的,所以预缓存清单对于缓存 Vue 应用程序非常重要 shell 因为静态资产通常在编译时被分解成块,它会每次(重新)构建应用程序时,在服务工作者中引用这些块对您来说非常乏味。

要预缓存静态资源,您可以将此代码放在 service-worker.js 文件的开头(您也可以使用 try/catch 语句):

if (workbox) {
    console.log(`Workbox is loaded`);

    workbox.precaching.precacheAndRoute(self.__precacheManifest);

} 
else {
    console.log(`Workbox didn't load`);
}

然后您可以继续在同一个文件中正常编程您的 service worker,或者使用 basic service worker API or by using workbox's API。当然,不要犹豫,把这两种方法结合起来。

希望对您有所帮助!

作为上述答案的补充:我写了一个小指南,介绍如何使用上面的设置进一步向自定义服务工作者添加一些功能。你可以找到它 here.

要牢记四点:

  1. vue.config.js 中的 Workbox 配置为 InjectManifest 模式,将 swSrc 键指向 /src
  2. 中的自定义 service-worker 文件
  3. 在这个自定义服务工作者中,一些行将在构建过程中自动添加,用于导入 precache-manifestworkbox CDN。需要在自定义 service-worker.js 文件中添加以下行以实际预缓存清单文件:

    self.__precacheManifest = [].concat(self.__precacheManifest || []);
    workbox.precaching.suppressWarnings();
    workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
    
  4. 监听registerServiceWorker.js文件中的注册事件。您可以使用作为第一个参数传递给事件处理程序的注册对象,将 post 消息发送到 service-worker.js 文件:

    ...
    updated(registration) {
      console.log("New content is available; please refresh.");
      let worker = registration.waiting
      worker.postMessage({action: 'skipWaiting'})
    },
    ...
    
  5. 订阅 service-worker.js 文件中的消息并采取相应行动:

    self.addEventListener("message", (e)=>{
        if (e.data.action=='skipWaiting') self.skipWaiting()
    })
    

希望这对某人有所帮助。