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.
要牢记四点:
- 将
vue.config.js
中的 Workbox 配置为 InjectManifest
模式,将 swSrc
键指向 /src
中的自定义 service-worker 文件
在这个自定义服务工作者中,一些行将在构建过程中自动添加,用于导入 precache-manifest
和 workbox CDN
。需要在自定义 service-worker.js
文件中添加以下行以实际预缓存清单文件:
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
监听registerServiceWorker.js
文件中的注册事件。您可以使用作为第一个参数传递给事件处理程序的注册对象,将 post 消息发送到 service-worker.js
文件:
...
updated(registration) {
console.log("New content is available; please refresh.");
let worker = registration.waiting
worker.postMessage({action: 'skipWaiting'})
},
...
订阅 service-worker.js
文件中的消息并采取相应行动:
self.addEventListener("message", (e)=>{
if (e.data.action=='skipWaiting') self.skipWaiting()
})
希望这对某人有所帮助。
在我的第一个 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.
要牢记四点:
- 将
vue.config.js
中的 Workbox 配置为InjectManifest
模式,将swSrc
键指向/src
中的自定义 service-worker 文件
在这个自定义服务工作者中,一些行将在构建过程中自动添加,用于导入
precache-manifest
和workbox CDN
。需要在自定义service-worker.js
文件中添加以下行以实际预缓存清单文件:self.__precacheManifest = [].concat(self.__precacheManifest || []); workbox.precaching.suppressWarnings(); workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
监听
registerServiceWorker.js
文件中的注册事件。您可以使用作为第一个参数传递给事件处理程序的注册对象,将 post 消息发送到service-worker.js
文件:... updated(registration) { console.log("New content is available; please refresh."); let worker = registration.waiting worker.postMessage({action: 'skipWaiting'}) }, ...
订阅
service-worker.js
文件中的消息并采取相应行动:self.addEventListener("message", (e)=>{ if (e.data.action=='skipWaiting') self.skipWaiting() })
希望这对某人有所帮助。