【问题标题】:Vue Cli 3 how to use the official PWA plugin ( Service Worker )Vue Cli 3 如何使用官方 PWA 插件(Service Worker)
【发布时间】:2018-12-15 06:55:30
【问题描述】:

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

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

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

【问题讨论】:

  • 一些人似乎已经达成的替代方案是干脆不使用这个插件和它提供的样板,而是按照他们可以在网上找到的任何文档创建自己的服务工作者。这是一个可行的解决方案,但我想我会在周末给这个,看看这个插件是否可以实际使用
  • 我认为这可能更多的是您对服务人员的了解,而不是真正的 vue 相关问题。
  • 很有可能.. 很好的观察
  • 我曾经对 vue-cli 3 PWA 插件有同样的问题。文档不太理想,你是对的。我试图用我在处理这个问题时获得的所有知识来回答你的问题。希望对你有帮助。
  • 是的@LandryBETE 这正是我所希望的。当我在 9 月份看到您的回复时,我已经保存了这个选项卡,现在才打开它(幸运的是,我的工作项目直到现在还没有要求我深入开发 PWA 功能)。非常感谢您提供如此丰富、深入的回应,我相信这将帮助无数人

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


【解决方案1】:

正如已经指出的,这更像是一个“服务工作者”问题,而不是一个“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 中提供一些挂钩。这些通常用于调试目的,而不是实际对 service worker 进行编程。您可以通过注意到 registerServiceWorker.js 文件将被捆绑到 app.js 文件中并在主线程中运行来理解它。

vue-cli 3 官方 PWA 插件基于 Google 的 workbox,因此要使用 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 的变量中。您必须在生产模式下构建您的应用程序才能确保是这种情况。

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

要预缓存静态资源,您可以将此代码放在 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 APIworkbox's API 继续在同一个文件中正常编程您的服务工作者。当然,不要犹豫,将这两种方法结合起来。

希望对你有帮助!

【讨论】:

  • PWA 插件的默认 workboxPluginModeGenerateSW,因此您实际上不需要在公共目录中创建 SW 文件,因为工作箱会为您执行此操作。同样重要的是要了解,虽然 _registerServiceWorker.js 文件确实只是注册了一个服务工作者,但vue-cli 的 PWA 插件实际上也(同样,默认情况下)为您创建了一个 SW(当为生产而构建时)默认情况下成功缓存您的整个应用以供离线使用。
  • 不错。 vue.config.js 成功了,现在它运行良好。不过只有一个问题:为什么我们需要那个额外的vue.config.js 文件,它不是已经加载到“register()”中了吗?就像...样板文件没有制作那个额外的文件,但是为什么呢?
【解决方案2】:

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

要记住的四个主要事项:

  1. vue.config.jsInjectManifest 模式下配置Workbox,将swSrc 键指向/src 中的自定义service-worker 文件
  2. 在这个自定义的 service-worker 中,一些行将在构建过程中自动添加用于导入 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()
    })
    

希望这对某人有所帮助。

【讨论】:

  • 非常有帮助的好文章!它对我很有用。也许 cli-plugin-pwa 很快就会添加这些额外的功能(用户提示、skipWaiting 等)作为更简单的 GenerateSW 的一部分。在那之前,这正是我所需要的。
  • +1000 我到处寻找完整的图片,但这是我唯一找到它的地方。如果您正在编写自己的 Service Worker,Google 开发指南会给出完整的画面,但默认情况下 Vue PWA 插件会为您构建它。 Vue PWA 插件文档不是很有帮助。 register-service-worker npm 模块实际上只为您提供基本的钩子,但默认情况下不监听消息。所以这非常有用,因为它将它们联系在一起。
  • 如果在工作箱版本 v4.1.0 或更高版本中使用generateSW 模式,self.addEventListener('message', (event) => { if (event.data && event.data.type === 'SKIP_WAITING') { self.skipWaiting(); } }); 已存在于生成的service-worker.js
猜你喜欢
  • 2019-03-18
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 2018-09-29
  • 2019-01-08
  • 2019-07-18
  • 2023-03-16
  • 2020-11-20
相关资源
最近更新 更多