workbox: Unexpected token < error after redeploy (InjectManifest Mode)

Library Affected: “@vue/cli-plugin-pwa”: “^3.6.0”,

Browser & Platform: Google Chrome for Android

Issue or Feature Request Description: I bundle my website/PWA, where I use a couple of Web Components, using the workbox-webpack-plugin.

Everything works smooth and well till I redeploy the project (hosted on Netlify). On my phone/desktop, if I clean my cache and access the website/pwa, all good, worker works correctly. Later on, once I release a new version, where I did several changes, and deploy it to the hosting and if I try to access the website/pwa , then I’ll face the following error: Uncaught SyntaxError: Unexpected token <

On checking network requests, I see that a request is made to an older app.[hash].js file which belonged to previous deploy. It is unable to find this file as it is getting deleted when new sw is activated.

const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin') module.exports = { configureWebpack: { plugins: [ new VuetifyLoaderPlugin() ] }, devServer: { disableHostCheck: true, }, lintOnSave: false, pwa: { workboxPluginMode: 'InjectManifest', workboxOptions: { swSrc: 'src/service-worker.js' } } }

A similar issue is raised #1528 , #1783

Please help.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (3 by maintainers)

Most upvoted comments

Hey @jeffposnick , thanks for the resources, I’ve gone through them and looks like “refreshing” is a complicated thing to do.

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' +
        'For more details, visit https://goo.gl/AFskqB'
      )
    },
    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.[update found]')
    },
    updated (registration) {
      console.log('New content is available; please refresh.');
      let worker = registration.waiting
      Events.$emit("showStatus", {text: "New Content is available. Please Reload the page.",timeout: 0})
      
      worker.postMessage({action: 'skipWaiting'})
    },
    offline () {
      console.log('No internet connection found. App is running in offline mode.')
      Events.$emit("showStatus", {text: "You are viewing content offline."})
    },
    error (error) {
      console.error('Error during service worker registration:', error)
    }
  })
  }

We are using vue-cli3-pwa-plugin and this is the boilerplate kind of thing for registration code. As you can see, I’m sending the postMessage after the update( checking if registration.waiting) which then does skipWaiting

self.addEventListener("message", (e)=>{
  if (e.data.action=='skipWaiting') {
    self.skipWaiting()
  }
})

This is an approach that is suggested by workbox too. But it just breaks my app when I reload the page after a new service worker is activated, since it tries to find an old cached html file that is not updated well in sw activation phase. The app breaks because it still uses an old html file from the cache that has links to old js files that can’t be found anymore. What am I missing here? Is there a way to use workbox advanced recipe for refreshing using this vue-pwa boilerplate?

In another case, I just deleted the code for skipWaiting and tried to activate new sw after closing all the tabs and opening in new tab. While activation has been successful, after a page reload it’s still fetching the old html file and js files that do not exist anymore.

Can you explain me the order of these events for a bug free pwa while using workbox webpack plugin:

  1. A new code change happens, we redeploy. 1.Registration and Installation happen first. 2. Cache cleanup and new precache manifest are generated during activation which should remove my old html and js and replace with newer ones. 3. If we call skipWaiting it activates immediately so chances are that it breaks the existing clients using old version 4. If I don’t deal with skipWaiting, then I need to close all tabs and reopen in new tab to see it activated. 5. We refresh the page to see the new content.

This is what I understood about the life cycle, correct me if I’m wrong I would love to understand it better. But I would be glad if you could help me know why my app is using old html file after a page refresh while sw has been activated correctly.

Also, my issue is more related to #1528 and looks like it is solved in workboxV4. But I’m using vue-cli-pwa-plugin which also has workbox-webpack-plugin as dependency. While I’m trying to update the pwa-plugin to latest 3.7.0 which possibly has updated workboxv4, it is still showing me workbox-3.6.3 in package-lock.json. Any idea how this works?

Thanks