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

时间:2018-07-06 16:13:49

标签: vue.js service-worker vue-cli pwa

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

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

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

2 个答案:

答案 0 :(得分:32)

正如已经指出的那样,与其说是“ 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 文件中的所有代码都是注册服务工作者并为其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属性添加到config对象。这些设置将允许您创建位于public/service-worker.js的自定义服务工作程序,并使工作箱在其中注入一些代码:预缓存清单。这是一个.js文件,其中已编译静态资产的引用列表存储在通常名为self.__precacheManifest的变量中。您必须以生产模式构建应用程序,以确保确实如此。

由于它是在生产模式下由工作箱自动生成的,因此预缓存清单对于缓存Vue应用程序外壳非常重要,因为静态资产通常在编译时分解为大块,这对于您来说非常繁琐。每次(重新)构建应用程序时,请在服务工作者中引用这些块。

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

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

    workbox.precaching.precacheAndRoute(self.__precacheManifest);

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

然后,您可以继续使用basic service worker API或使用workbox's API在同一文件中继续对服务工作者进行常规编程。当然,不要犹豫,将这两种方法结合起来。

希望对您有帮助!

答案 1 :(得分:21)

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

要记住的四件事:

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

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

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

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

希望这对某人有帮助。