New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with new builds #3574

Closed
rogovdm opened this Issue Dec 10, 2017 · 22 comments

Comments

Projects
None yet
@rogovdm

rogovdm commented Dec 10, 2017

After each new build I have this error in production:

Uncaught SyntaxError: Unexpected token <

And I cannot understand the exact reasoning behind this. And this error disappers after couple of page refreshes.

More formaly

  • Making first build. Everything is fine.
  • Making second build. Having an error in console about problems with loading previous build.
  • Refreshing page. Refreshing page. Refreshing page. Everything is fine.

Conclusion

Somehow because of service worker chrome is loading previous js build. Thus server cannot serve it so I have a parsing error in console. After service worker updates now chrome is loading last build and everything is working fine.

Maybe, maybe service worker also cached index.html? Is t

Questions

What is messed up? How to force chrome load latest build after updates? Is it a good idea to cache index.html? (if that is true)

Info

  • Latest Chrome
  • Latest CRA
  • serving with simple express.js server
@andrei-anisimov

This comment has been minimized.

andrei-anisimov commented Dec 12, 2017

I have the same issue. I believe the reason is that the service-worker caches index.html with the old .js script file name (different hash). Both index.html and service-worker.js files have cache-control: public, must-revalidate, proxy-revalidate, max-age=0. Is there a way for the service worker to refetch index.html?

@rogovdm

This comment has been minimized.

rogovdm commented Dec 13, 2017

@andrei-anisimov

the only way I see to fix this problem is to store several builds, not only the latest one. But it is hard to believe that this is the best practice or the best defaults. So I am leaning to an option that I am missing something.

But what am I missing?

@andrei-anisimov

This comment has been minimized.

andrei-anisimov commented Dec 13, 2017

sw-precache has useful info:

  • sw-precache uses a cache-first strategy, which results in a copy of
    any cached content being returned without consulting the network. A useful
    pattern to adopt with this strategy is to display a toast/alert to your users
    when there's new content available, and give them an opportunity to reload the
    page to pick up that new content (which the service worker will have added to
    the cache, and will be available at the next page load). The sample service-worker-registration.js file illustrates the service worker lifecycle event you can listen for to trigger this message.
@rogovdm

This comment has been minimized.

rogovdm commented Dec 13, 2017

@andrei-anisimov, yeap, but in order to display that notification i need serve some checker.js (or make it a part of build.js) from index.html and that is what I cannot do. :|

@rogovdm

This comment has been minimized.

rogovdm commented Dec 16, 2017

Maybe I can ask like this: is this an expected behaviour of PWA? Otherwise it is a mistake on my side.

@gaearon

This comment has been minimized.

Member

gaearon commented Jan 8, 2018

@jeffposnick can answer this, but in the meantime you can opt out of caching if it causes issues.

@jeffposnick

This comment has been minimized.

Contributor

jeffposnick commented Jan 9, 2018

As @gaearon mentions, you can opt-out of caching, but I'd obviously like to help get to the bottom of any problems you're having!

Maybe I can ask like this: is this an expected behaviour of PWA? Otherwise it is a mistake on my side.

Serving index.html cache-first on browsers that support service workers is the expected default behavior.

yeap, but in order to display that notification i need serve some checker.js (or make it a part of build.js) from index.html and that is what I cannot do. :|

The service worker lifecycle automatically handles checking for updates, and by default, there's a very basic example of logging a message in the JS console when updated resources are detected:

https://github.com/facebookincubator/create-react-app/blob/72b6eb8c3c65e6ed0f2413708069287311a386c2/packages/react-scripts/template/src/registerServiceWorker.js#L61-L74

This message isn't part of the UX, but you could replace the console.log() statements with something more visible. Alternatively, #2426 is an open PR that makes a visible message appear by default.

the only way I see to fix this problem is to store several builds, not only the latest one. But it is hard to believe that this is the best practice or the best defaults. So I am leaning to an option that I am missing something.

I'm curious as to how you're loading the JavaScript files that show up as missing. Are they lazy-loaded after certain actions have taken place? Or are they loaded immediately as part of the initial HTML's parsing?

@rogovdm

This comment has been minimized.

rogovdm commented Jan 12, 2018

Or are they loaded immediately as part of the initial HTML's parsing?

I believe it is immidiately. I am using default index.html from CRA.

What I end up is outing out from cache-first strategy. This made me sad, but I did not manage to wrap my head why the bug took place.

Recently I had another idea. Can you validate it and maybe if it's true we can add some thing do README.md

Here is an idea. Maybe in order to have a proper service-worker workflow I must serve cached index.html? I believe in order to turn cache off I remove caching index.html. And what happened than was:

  • after visiting website new index.html file was served.

And this somehow conflicted with what was already cached on a client.

I am not sure if I am clear enough just trying to figure out what was happening.

If my idea is right we can add some info about cache index.html file. For me this situations can be described and ultra tricky. :)

P. S. Thanks for taking time and care on CRA.

@airqb

This comment has been minimized.

airqb commented Jan 14, 2018

@jeffposnick

This comment has been minimized.

Contributor

jeffposnick commented Jan 16, 2018

Here is an idea. Maybe in order to have a proper service-worker workflow I must serve cached index.html? I believe in order to turn cache off I remove caching index.html. And what happened than was:

Do you mean that you explicitly went into the browser's DevTools and cleared out the Cache Storage API entry for index.html? Yes, if you took that manual approach, I'd imagine that you could run into mismatches between index.html and the versioned subresources that it needs to load.

@BlakeWilliams

This comment has been minimized.

BlakeWilliams commented Feb 13, 2018

We're running into this issue and it's seemingly because the JS bundle isn't included in the generated build/service-worker.js file in this project and I'm not entirely sure why that's happening.

@jeffposnick

This comment has been minimized.

Contributor

jeffposnick commented Feb 13, 2018

This sounds like #3882 (comment). Probably best to consolidate the discussion there.

@antoinerousseau

This comment has been minimized.

antoinerousseau commented Mar 25, 2018

I have the same issue and I'm not using the service worker at all.

My project is hosted on Firebase Hosting and uses an error reporting tool that allows me to see that when I build and deploy a new version, some users get that SyntaxError because their index.html is trying to load a main.[hash].js that no longer exists... which means there is something wrong with the cache control (I'm not an expert on this...) because if the browser can load the old index.html, why can't it load the old JS bundle too?

It happened on various browsers like Firefox mobile 59 for Android, Chrome mobile 65 for Android, Chrome 60 and 65 for Windows, Chrome 62 for macOS, etc.

Should I tweak Firebase hosting to redirect all the missed main.*.js to the new one in my deploy script?

@Shpadoinkle

This comment has been minimized.

Shpadoinkle commented Jun 12, 2018

yep same here. Have tried adding header caching rules to the header section with no success.

Currently trying to unregister the serviceWorker but this seems like a horrid way to get around this bug.

I swear this used to work just fine. So not sure where the issue began.

But judging on the history of react devs and how often issue threads just close down due to inactivity, I doubt this will be addressed any time soon.

@antoinerousseau

This comment has been minimized.

antoinerousseau commented Jun 12, 2018

Fyi, my ugly temporary workaround for now is to dynamically generate firebase.json before publishing to firebase hosting, using this script:

#!/usr/bin/env node

'use strict'

const config = {
  hosting: {
    public: 'build',
    rewrites: [
      {
        source: '**',
        destination: '/index.html'
      }
    ],
    redirects: []
  }
}

const fs = require('fs')

const path = require('path')
const folders = fs.readdirSync(path.resolve(__dirname, 'build/static'))
folders.forEach((folder) => {
  const files = fs.readdirSync(path.resolve(__dirname, 'build/static', folder))
  files.forEach((file) => {
    config.hosting.redirects.push({
      source: `/static/${folder}/${file.replace(/^main\.(\w+)/, 'main.!($1)')}`,
      destination: `/static/${folder}/${file}`,
      type: 301
    })
  })
})

fs.writeFileSync('firebase.json', JSON.stringify(config))
@Stas-Buzunko

This comment has been minimized.

Stas-Buzunko commented Jul 1, 2018

@antoinerousseau error disappeared but it always loads previous build, when i did hard reload it did load latest build, but on next refresh it loaded previous build as well
you can see my console logs v12 is old build, v13 is a new one, after hard reload i got v13 and but again v12
screen shot 2018-07-01 at 21 37 33

@binki

This comment has been minimized.

binki commented Aug 3, 2018

For me, my builds are omitting static/js/main.«hash».js from the generated service-worker.js. So when my browser loads the precached index.html and main.«hash».css just fine, it tries to make a real request for the .js which, after an app update, no longer exists.

Is the generated service-worker.js supposed to have main.«hash»js present when it is working properly? Could that be the issue?

@binki

This comment has been minimized.

binki commented Aug 3, 2018

I’m working around my issue with https://gist.github.com/binki/e6558065360e47238240857d6cee611f . I need to update my react-scripts to the latest version (I’m currently on 1.0.7), I will see if that helps.

@Stas-Buzunko

This comment has been minimized.

Stas-Buzunko commented Aug 21, 2018

#3882 (comment) worked for me

rdubigny added a commit to betagouv/signup-front that referenced this issue Aug 24, 2018

@nfantone

This comment has been minimized.

nfantone commented Oct 4, 2018

Hit the same issue again today with 2.0.4. Comment above did not solve it for me, unfortunately. Related: #3882 (comment)

@stale

This comment has been minimized.

stale bot commented Nov 3, 2018

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 7 days if no further activity occurs.

@stale stale bot added the stale label Nov 3, 2018

@stale

This comment has been minimized.

stale bot commented Nov 8, 2018

This issue has been automatically closed because it has not had any recent activity. If you have a question or comment, please open a new issue.

@stale stale bot closed this Nov 8, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment