1

I'm trying to configure a custom service workers on Vuejs with Webpack but it's not completely working with the events or workbox (depending where I'm calling the sw.js file.

Following workbox guide from Google I've configured the SW to be registered and caching data but as I mentioned before depending on where I call the SW is doing wrongs things (or maybe I'm just dumb).

For example, if I register the file SW on index.html like this:

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>

... my SW is registered but it's unable to catch events (offline and online) on the SW file showed below (service-worker.js) BUT I'm able to use workbox:

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);

... If I remove the script tag from index.html and put a call on the main.js and modify the service-worker.js like this:

main.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);

... On this situation, I'm able to hear the events, but I'm UNABLE to use workbox (I receive an error on console that it's undefined.)


Do you have an idea what could be doing wrong?

1 Answer 1

3

I think you have confused some things here, let me explain :)

Service Worker and the web application/web page itself DO NOT share the same execution context. If you define a variable in your SW script, your "normal" JavaScript on the page cannot access it and vice versa. They are COMPLETELY separate.

For this reason, if you put something like this:

import store from './store/index';

in your service-worker.js (Service Worker script), it DOES NOT mean the same thing as having the same line of code in your main.js. You CANNOT dispatch Vuex actions from SW script.

How can you communicate from SW to "main bundle"? Use postMessage. With postMessage you can send JSON messages from the page to the SW and from the SW to the page. The handler of the messages can then dispatch Vuex actions etc.

Does this clear things up for you?

Sign up to request clarification or add additional context in comments.

2 Comments

Hey Pate, yes it's more clear now, I also already solve this part, just forgot to check it here, thanks a lot for the help!
@Poshox that's great!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.