Working service-worker seems unreachable in a Vue.js PWA

Viewed 16

I've been stuck for the past weeks, it's time for me to reach for some help.

I'm working on a VueJS PWA. It's a new thing for me. I'm trying to setup a basic service-worker to start.

Everything seems good: my service-worker is activated and running, I can install my application.

Still I have two issues:

  1. The main one, when I use Chrome developer tools and Push a message, it doesn't seem to reach my service-worker. Neither if I click my Update button. In some rare cases, I've reached my debugger instruction, it seems to be when I modify code in my project (and get the refresh in the webbrowser), but I'm not even sure.
  2. An other less important issue. I got through it but, still, it bothers me. When my service-worker-dev.js file is in src folder. It's copied and modified to dist folder, but it doesn't seem to be reachable when I try to load it from the webbrowser. To do so, I have to move it in public folder. He is also copied in the dist folder but this time, it is loading from the webbrowser.

vue.config.js

module.exports = {
  transpileDependencies: [
    'vuetify'
  ],
  pwa: {
    name: "MyWebApp",
    themeColor: "#42b983",
    msTileColor: "#42b983",
    appleMobileWebAppCache: "yes",
    favicon32: 'img/icons/favicon-32x32.png',
    favicon16: 'img/icons/favicon-16x16.png',
    appleTouchIcon: 'img/icons/apple-touch-icon-152x152.png',
    maskIcon: 'img/icons/safari-pinned-tab.svg',
    msTileImage: 'img/icons/msapplication-icon-144x144.png',
    manifestOptions: {
      name: "MyWebApp",
      short_name: "MyWebApp",
      background_color: "#42b983",
      theme_color: "#4DBA87",
      display: "standalone",
      start_url: "."
    },
    workboxPluginMode: "InjectManifest",
    workboxOptions: {
      swSrc: "src/service-worker-dev.js"
    }
  }
}

main.js

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

import Home from './components/Home.vue'
import Contact from './components/Contact.vue'

import App from './App.vue'
import vuetify from './plugins/vuetify'
import "./registerServiceWorker";

const router = new VueRouter({
  mode: 'history',
  base: __dirname,
  routes: [
    { path: '/', component: Home },
    { path: '/:userId/:commentId', component: Home },
    { path: '/contact', component: Contact },
  ]
});

Vue.config.productionTip = false;

new Vue({
  router,
  vuetify,
  render: h => h(App),
}).$mount('#app')
registerServiceWorker.js
/* eslint-disable no-console */

import { register } from 'register-service-worker'

register(`./service-worker-dev.js`, {
    ready() {
        console.log(
            'App is being served from cache by a service worker.\n'
        );
    },
    registered() {
        console.log('Service worker has been registered.');
    },
    cached() {
        console.log('Content has been cached for offline use.');
    },
    updatefound() {
        console.log('New content is downloading.');
    },
    updated(registration) {
        console.log('New content is available; please refresh.');
        let confirmationResult = confirm("New content found! Do you want to reload the app?");
        if (confirmationResult)
            registration.waiting.postMessage({ action: "skipWaiting" });
    },
    offline() {
        console.log('No internet connection found. App is running in offline mode.');
    },
    error(error) {
        console.error('Error during service worker registration:', error);
    },
    message(message) {
        console.log(message);
    }
});

let refreshing;
navigator.serviceWorker.addEventListener("controllerchange", () => {
    if (refreshing) return;
    window.location.reload();
    refreshing = true;
});

navigator.serviceWorker.addEventListener("message", (e) => {
    debugger;
    console.log(e);
});

service-worker-dev.js

workbox.core.setCacheNameDetails({ prefix: "MyWebApp" });

self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

// install new service worker when ok, then reload page.
self.addEventListener("message", async msg => {
  debugger;
  console.log("message", msg);
  const clients = await self.clients.matchAll({ type: 'window' });
  for (const client of clients) {
    debugger;
    client.postMessage(msg);
  }

  if (msg.data.action == 'skipWaiting') {
    self.skipWaiting()
  }
});

self.addEventListener('fetch', function (event) {
  event.respondWith(async function () {
    try {
      var res = await fetch(event.request);
      var cache = await caches.open('cache');
      cache.put(event.request.url, res.clone());
      return res;
    }
    catch (error) {
      return caches.match(event.request);
    }
  }());
});

UPDATE registerServiceWorker.js

/* eslint-disable no-console */

import { register } from 'register-service-worker'
//TODO: Replace with right service worker
register(`./service-worker-dev.js`, {
    ready() {
        console.log(
            'App is being served from cache by a service worker.\n'
        );
    },
    registered() {
        console.log('Service worker has been registered.');
    },
    cached() {
        console.log('Content has been cached for offline use.');
    },
    updatefound() {
        console.log('New content is downloading.');
    },
    updated(registration) {
        console.log('New content is available; please refresh.');
        let confirmationResult = confirm("New content found! Do you want to reload the app?");
        if (confirmationResult)
            registration.waiting.postMessage({ action: "skipWaiting" });
    },
    offline() {
        console.log('No internet connection found. App is running in offline mode.');
    },
    error(error) {
        console.error('Error during service worker registration:', error);
    },
    message(message) {
        console.log(message);
    }
});

let refreshing;
navigator.serviceWorker.addEventListener("controllerchange", () => {
    if (refreshing) return;
    window.location.reload();
    refreshing = true;
});

navigator.serviceWorker.addEventListener("message", (e) => {
    debugger;
    console.log(e);
});
0 Answers
Related