Polymer / shop

The Shop app
https://shop.polymer-project.org/
986 stars 494 forks source link

App does not update because old SW URLs 404 #150

Closed ithinkihaveacat closed 6 years ago

ithinkihaveacat commented 6 years ago

https://shop.polymer-project.org/list/mens_outerwear is mostly blank (no products):

screen shot 2017-10-21 at 11 43 52 am

(Problem seems to be that https://shop.polymer-project.org/data/mens_outerwear.json is 404ing.)

ithinkihaveacat commented 6 years ago

The actual cause seems to be that at some point /service-worker.js got moved to /es6-unbundled/service-worker.js. /service-worker.js now 404s, so Chrome can't collect the update, and continues to use the old version. Maybe a mismatch between the "new" front-end code, and the "old" service worker?

screen shot 2017-10-21 at 11 51 29 am

ithinkihaveacat commented 6 years ago

To summarize, this bug affects browsers that: (1) support service workers and (2) loaded https://shop.polymer-project.org/list/mens_outerwear at some time in the past (collecting a /service-worker.js that no longer exists).

The fix probably involves checking whether the active service worker is the expected one, and unregistering if so (some complications around the initial registration flow, though):

const expectedServiceWorker = 'es6-unbundled/service-worker.js'

const isServiceWorker = (path) => navigator.serviceWorker.ready.then(r => 
  r.active.scriptURL === `${r.scope}${path}`
);

if (!await isServiceWorker(expectedServiceWorker)) {
  // wrong service worker is active, register the new one
}

(@jeffposnick, do you have any thoughts on how to safely "move" a service worker from one URL to another?)

jeffposnick commented 6 years ago

See https://github.com/w3c/ServiceWorker/issues/204 for ideas about resolving this on the spec-level.

As of right now, the best practice would be to ship a no-op /service-worker.js (see https://stackoverflow.com/a/38980776/385997 for an example) and then the next time the fresh content is loaded from the network, it will pull in the code the re-registers with the new location.

Or... just move the service worker from es6-unbundled/service-worker.js back to/service-worker.js.

keanulee commented 6 years ago

Given that the URL of the service worker needs to be long-lived (just like site URLs like "/list/mens_outerwear"), I think we need to keep "https://shop.polymer-project.org/service-worker.js" around and use it to import the build-specific SW. We can rewrite an importScripts() inside that SW just like how we rewrite the <base> tag for page URLs.

importScripts('es6-bundled/service-worker.js');

This would require support from prpl-server-node. Thoughts @justinfagnani @aomarks @frankiefu ?

aomarks commented 6 years ago

We're thinking that we'll update prpl-server to automatically serve a tiny self-unregistering service worker for any would-be-404 "service-worker.js" URL. This simulates what I think we want from the spec at https://github.com/w3c/ServiceWorker/issues/204.

justinfagnani commented 6 years ago

This may be another reason to explore producing multiple builds overlayed into the same build output folder - in this case we could look at having a single service-worker, that pre-caches the appropriate build for the browser that loads it.