Pwa-module: Service worker cache not updating on new deploy on Netlify

Created on 22 Feb 2019  路  25Comments  路  Source: nuxt-community/pwa-module

Version

v3.0.0-beta.8

Reproduction link

https://github.com/bovas85/nunziellasalluce.com

Steps to reproduce

fork the repo and host it on Netlify by linking your master branch commits
once you build the first time, visit the netlify link to make sure it registers a service worker
make a change and commit again, re visit the netlify link and some parts of the website will be broken (css missing or random issues)

The service worker will say that it was registered in 1970:
Capture.JPG

What is expected ?

service worker updates properly

What is actually happening?

broken sw.js and cache busting

This bug report is available on Nuxt community (#c99)

Most helpful comment

I removed the filenames, optimization and presets. Seems to be working in FF, Chrome, Safari and IE11. Thanks @pi0 and @bovas85

All 25 comments

Example in this repo is customized for development. Can you please ensure this is also happening for nuxt7.surge.sh and nuxt7.netlify.com? (Or bootstrap-vue.js.org)

@pi0 what do you mean with customised for dev?
I had an issue with some server config regarding the caching but the service worker registration date is still 1970

As mentioned in Discord it seems the date is fine and shows correctly when using curl. I'll close this and revisit once I publish a new website version.

I have similar issues. I had to unregister the service worker before the website was viewable.

The error i get in firefox:
TypeError: e[t] is undefined

In Chrome
Runtime TypeError: Cannot read property 'call' of undefined at __webpack_require__

Is there anything specific i have to do when updating the website running the PWA module?

@maziarz Don't you use any config related to extractCSS?

@maziarz Don't you use any config related to extractCSS?

I have not configured extractCSS at any point. I use @nuxtjs/style-resources for some global SCSS variables. Tried to set Netlify headers for sw.js but that made no difference either:

/sw.js
    cache-control: max-age=0,no-cache,no-store,must-revalidate

What's your nuxt.config?

module.exports = {
  /*
  ** Headers of the page
  */
  head: {
    title: 'Landingpage',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { name: 'fragment', content: '!' },
      { name: 'robots', content: 'index, follow' },
      {'http-equiv': 'X-UA-Compatible', content: 'IE=edge'}
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ],
    script: [
      { type: 'text/javascript', src: 'https://wchat.freshchat.com/js/widget.js' }
    ]
  },
  mode: 'spa',
  /*
  ** Customize the progress bar color
  */
  loading: { color: '#fb525a' },
  loadingIndicator: {
    name: 'pulse',
    color: '#FB525A',
    background: 'black'
  },
  /*
  ** Build configuration
  */
  modules: [
    ['@nuxtjs/pwa', {
      icon: false
    }],
    ['nuxt-vuex-localstorage', {
      localStorage: ['teamCreation']
    }],
    '@nuxtjs/moment',
    '@nuxtjs/sitemap',
    'nuxt-stripe-module',
    '@nuxtjs/style-resources',
    ['nuxt-i18n', {
      locales: [
        { code: 'en', iso: 'en-US' }
      ],
      defaultLocale: 'en',
      strategy: 'prefix',
      vueI18n: {
        fallbackLocale: 'en'
      }
    }],

  ],
  styleResources: {
    scss: [
      '~assets/scss/abstracts/_variables.scss',
      '~assets/scss/abstracts/_mixins.scss',
      '~assets/scss/abstracts/_animations.scss'
    ]
  },
  sitemap: {
    generate: true,
  },
  babel: {
    presets: ({ isServer }) => {
      return [[
        '@nuxt/babel-preset-app',
        {
          buildTarget: isServer ? 'server' : 'client', // for auto import polyfill
          useBuiltIns: 'entry'
        }
      ]]
    }
  },
  build: {
    transpile: [
      'nuxt-vuex-localstorage',
      'extract-css-chunks-webpack-plugin', // https://github.com/nuxt/nuxt.js/issues/5065
      'normalize-url'
    ],
    filenames: {
      chunk: ({ isDev }) => isDev ? '[name].js' : '[name].js'
    },
    optimization: {
      splitChunks: {
        chunks: 'all',
        name: true
      }
    },
    // analyze: true,


    /*
    ** Run ESLint on save
    */


    extend (config, ctx) {
      ctx.loaders.less.javascriptEnabled = true
      ctx.loaders.less.modifyVars = {
        'font-family':                  'ProximaNovaReg',
        'primary-color':                '#479ff1',
        'component-background':         '#262626',
        'input-bg':                     '#222222',
        'input-border-color':           '#222222',
        'input-color':                  '#ECECEC',
        'input-addon-bg':               '@input-bg',
        // Text colors
        'highlight-color':              '#FB525A',
        // Layout
        'layout-header-background':     '#161616',
        // Buttons
        'btn-primary-bg':               '#323232',
        // 'btn-default-bg':               '#323232',
        // 'btn-danger-bg':                '#FB525A',
        'btn-primary-color':            '#ECECEC',
        // Popover
        'popover-bg':                   '#242424',
        'popover-arrow-color':          '#242424',
        // Menu - Dark theme
        'menu-dark-bg':                 'none',
        'menu-dark-item-active-bg':     'none',
        'menu-item-bg':                 'none',
        'menu-item-active-bg':          'none',
        'menu-dark-color':              '#808080',
        'menu-dark-highlight-color':    '#ECECEC',
        'menu-highlight-color':         '#262626',
        'menu-item-color':              '#ECECEC',
        'menu-item-group-title-color':  '#ECECEC',
        // Modal
        'modal-header-bg':              '#262626',
        // Card
        'card-head-background':         '#262626',
        'card-actions-background':      '#262626',
        // Tooltips
        'tooltip-bg':                   '#303030'
      }

      config.module.rules.push({
        test: /\.(graphql|gql)$/,
        use: 'graphql-tag/loader',
        exclude: /(node_modules)/
      })
    }
  }
}

Try removing some rules especially the extract css ones.
I'd try upgrading nuxt as well as you are using some deprecated isClient isServer syntax

Try removing some rules especially the extract css ones.
I'd try upgrading nuxt as well as you are using some deprecated isClient isServer syntax

I am running the latest version of nuxt. Should i remove it from the transpile configuration?

This line may also make troubles when locally testing. Service wroker will be blindly cached:

chunk: ({ isDev }) => isDev ? '[name].js' : '[name].js'

This line may also make troubles when locally testing. Service wroker will be blindly cached:

chunk: ({ isDev }) => isDev ? '[name].js' : '[name].js'

I guess that this is not even necessary when using service workers? The guys over at netlify recommended told me that i should avoid hashing the chunks as they are already doing some cache-busting.

I removed the filenames, optimization and presets. Seems to be working in FF, Chrome, Safari and IE11. Thanks @pi0 and @bovas85

@pi0 @bovas85, i have been keeping a close eye on sentry and been noticing these Error: Loading chunk 64 failed, Error: Loading chunk 67 failed, Error: Loading chunk 1 failed, chunk number changes. Is this in any way related to the service worker?

Not sure, you could try naming your chunks during dynamic import and see if the browser loads new ones

@maziarz Not exactly related to pwa. Users encounter such error when you roll out a new version. It is better to serve content of (.nuxt/dist/client) from a CDN so both old and new chunks are available for users. A reverse proxy like Nginx or Cloudflare can also help caching chunks on requests

@pi0 but in essence this problem could be solved by not hashing the chunks, but actually naming them what the pages are named originally? I also came across this article: https://www.netlify.com/blog/2017/02/23/better-living-through-caching/
It would be to radical for me to change or add CDN's when using a service like Netlify.

Naming chunks without hash is not probably a good idea. You can setup CloudFlare on top of Netlify for more advanced CDN caching.

Naming chunks without hash is not probably a good idea. You can setup CloudFlare on top of Netlify for more advanced CDN caching.

To understand this problem better. Will it only occur towards users that are already on the website and attempts to navigate thus loading chunks OR for all users entering the website with the cached chunks?

@maziarz yes. New users receive HTML that refers to the new hashed manifest chunk. And it is Network First.

Got'cha @pi0. Thanks for the clarification!

@pi0

@maziarz yes. New users receive HTML that refers to the new hashed manifest chunk. And it is Network First.

I have some updates on this issue after talking to Netlify.

First of, i discussed with them the idea of adding something like CloudFlare:

Putting cloudflare in front of Netlify is not a supported configuration (see聽https://www.netlify.com/support-scope聽- it means they proxy to us) and results will not be better but worse in our experience.

Secondly they referred me to this discussion on Spectrum: https://spectrum.chat/react/general/how-to-handle-deployments-with-webpack-code-splitting~16dc5f85-0b4b-4eee-8693-066d82dcdc7f

There are some approaches mentioned here, a part from the offline-plugin:

  • The old school solution for this problem, btw, would be to store all the files of previous versions and have them uniquely named, e.g. with a hash in the name.
  • Another solution might be to make every chunk know the current version. So if if new one is being loaded, it checks for the version and if it doesn't match -- it simply reloads the page. Same for chunks which are missing, you reload the page when network error happens

As i understand this is a pretty common issue, could offline-plugin approach be the solution?

PS: If this is going off-topic, i would be more than glad to create a new issue.

Chiming in here as I've also been trying to use this module on Netlify with a static site build. I had gotten similar advice about not hashing my filenames which seemed to work well but we soon ran into problems and I had to roll back. If I were to continue not hashing my filenames, would the correct thing to do be to set the cacheAssets: false option in the configuration?

I'll probably try this out soon myself and report back but wanted to check if anyone had already done this.

Chiming in here as I've also been trying to use this module on Netlify with a static site build. I had gotten similar advice about not hashing my filenames which seemed to work well but we soon ran into problems and I had to roll back. If I were to continue not hashing my filenames, would the correct thing to do be to set the cacheAssets: false option in the configuration?

I'll probably try this out soon myself and report back but wanted to check if anyone had already done this.

Unfortunately i cannot be of any help here. I switched the SW completely off due to some big headaches getting to work properly, but however, i did end up switching off hashing on the filenames and it fixed the majority of my issues when deploying new versions of the site causing issues with loading chunks.

I use it just fine in Netflix static and it works.

Check my config here
https://github.com/bovas85/nunziellasalluce.com

Was this page helpful?
0 / 5 - 0 ratings