【问题标题】:Is correct to call the service worker from main.js file or from index.html?从 main.js 文件或 index.html 调用 service worker 是否正确?
【发布时间】:2019-09-06 06:40:44
【问题描述】:

我正在尝试使用 Webpack 在 Vuejs 上配置自定义服务工作者,但它不能完全处理事件或工作箱(取决于我调用 sw.js 文件的位置。

按照 Google 的工作箱指南,我已将 SW 配置为注册并缓存数据,但正如我之前提到的,取决于我在哪里调用 SW 做错事(或者我可能只是愚蠢)。

例如,如果我像这样在 index.html 上注册文件 SW:

index.html

<script>
    // Check that service workers are registered
    if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
            navigator.serviceWorker.register('service-worker.js').then(registration => {
                // registration.pushManager.subscribe({ userVisibleOnly: true, 
                //   applicationServerKey: key });
                console.log('SW registered: ', registration);
            }).catch(registrationError => {
                console.log('SW registration failed: ', registrationError);
            });
        });
    }
</script>

...我的 SW 已注册 但它无法捕获 SW 文件中的事件(离线和在线),如下所示 (service-worker.js) 但我可以使用工作箱

service-workers.js

import store from './store/index';

window.addEventListener('online', () => {
  console.log('Ando online compa');
  store.dispatch('IndexedDB/prueba');
});

window.addEventListener('offline', () => {
  console.log('Ando offline compa');
  store.dispatch('IndexedDB/prueba');
});

window.addEventListener('push', (event) => {
  const title = 'Get Started With Workbox';
  const options = {
    body: event.data.text(),
  };
  event.waitUntil(window.registration.showNotification(title, options));
});

workbox.core.skipWaiting();
workbox.core.clientsClaim();
workbox.precaching.precacheAndRoute(self.__precacheManifest);

...如果我从 index.html 中删除脚本标记并调用 ma​​in.js 并修改 service-worker.js 像这样:

ma​​in.js

import './vapidHelper';
import Vue from 'vue';
import './plugins/vuetify';
import VueSocketIO from 'vue-socket.io';
import App from './App.vue';
import router from './router';
import store from './store';
import './axiosConfig';
import initDB from './indexedDB/IndexedDB';
import './service-worker'; // <---- LINE

Vue.config.productionTip = false;
...

service-worker.js

import store from './store/index';

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('service-worker.js').then((registration) => {
      // registration.pushManager.subscribe({ userVisibleOnly: true, 
      //   applicationServerKey: key });
      console.log('SW registered: ', registration);
    }).catch((registrationError) => {
      console.log('SW registration failed: ', registrationError);
    });
  });

  window.addEventListener('online', () => {
    console.log('Ando online compa');
    store.dispatch('IndexedDB/prueba');
  });

  window.addEventListener('offline', () => {
    console.log('Ando offline compa');
    store.dispatch('IndexedDB/prueba');
  });

  window.addEventListener('push', (event) => {
    const title = 'Get Started With Workbox';
    const options = {
      body: event.data.text(),
    };
    event.waitUntil(window.registration.showNotification(title, options));
  });
}

workbox.core.skipWaiting();
workbox.core.clientsClaim();
workbox.precaching.precacheAndRoute(self.__precacheManifest);

...在这种情况下,我能够听到这些事件,但我无法使用工作箱(我在控制台上收到一个未定义的错误。)


你知道哪里出了问题吗?

【问题讨论】:

    标签: vue.js webpack service-worker workbox workbox-webpack-plugin


    【解决方案1】:

    我认为你在这里混淆了一些东西,让我解释一下:)

    Service Worker 和 Web 应用程序/网页本身不要共享相同的执行上下文。如果您在 SW 脚本中定义变量,则页面上的“普通”JavaScript 无法访问它,反之亦然。它们是完全分开的。

    因此,如果你这样写:

    import store from './store/index';
    

    在您的 service-worker.js(Service Worker 脚本)中,它与您的 main.js 中具有相同的代码行具有相同的含义。您不能从 SW 脚本调度 Vuex 操作。

    如何从 SW 与“主捆绑包”进行通信?使用 postMessage。使用 postMessage,您可以将 JSON 消息从页面发送到 SW,然后从 SW 发送到页面。然后消息的处理程序可以调度 Vuex 操作等。

    这对你有好处吗?

    【讨论】:

    • Hey Pate,是的,现在更清楚了,我也已经解决了这部分,只是忘了在这里检查,非常感谢您的帮助!
    • @Poshox 太棒了!!
    猜你喜欢
    • 2020-02-10
    • 2018-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多