vite-pwa / vite-plugin-pwa

Zero-config PWA for Vite

Home Page:https://vite-pwa-org.netlify.app/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Migrating app from registerType `autoUpdate` to `prompt` results in broken state

danielberndt opened this issue · comments

Hi there 👋

The first versions of my app have been published using registerType: "autoUpdate".
Now I'd like to offer a better UX and created an upgrade of my app to use registerType: "prompt".

It seems though that all clients that have the old version of the app loaded, won't be able to load a new version.

Looking into it, the devtools tell me that the new version is present, but the app/service worker won't trigger a reload. Refreshing the browser window doesn't load the new version either.

image

So it seems like users who have a registerType: "autoUpdate" version of the app loaded are stuck until they would manually remove the old service worker.

Is there something I can do make this type of migration possible?

@danielberndt I think it is a edge case and I don't know how to solve it directly, I'll ask to someone on workbox but I don't promise you anything .

I'm testing it using vue-router example, I build the pwa with autoUpdate, open it on chrome, then I rebuild it using prompt strategy but the old sw is used intead the new one:

imagen

but on the source code, both with the same code:

imagen

I get the sw with the new strategy if I close all chrome windows and then reopen the app again: tested on non private browsing.

imagen

and once reopened:

imagen

Thanks for the quick reply!

I've done some more experimenting. And I think I've somewhat succeeded by creating a custom sw.js containing code of both registerTypes:

[...]
self.skipWaiting();
clientsClaim();

self.addEventListener("message", (event) => {
  if (event.data && event.data.type === "SKIP_WAITING") self.skipWaiting();
});

Once all clients have loaded this version, I could remove the first two lines and the "prompt" strategy was working without these clients being stuck in the old version.

So maybe it's worth to add the addEventListener line even for the autoUpade type to ensure a migration is possible.

Not really sure this is something that needs to happen in this library or in workbox though.

@danielberndt The problem is that the sw is updated with the new strategy, but since we now have the prompt behavior the old app is still being used and so the new ReloadPrompt is not there (the new app is awaiting to be loaded, but the component that triggers the refresh isn't still loaded).

I suggest you to not do this, if your users are under your control (not a public app), you can hint them to close the browser and reopen the app once you deploy the new version.

Another approach: you can add an env property, for example VITE_CONTROL_APP and use import.meta.env.VITE_CONTROL_APP in the custom sw, if that variable is missing or false just use the skipWaiting otherwise use the addEventListener: you will need to deploy 2 versions, former with false to deploy the ReloadPrompt component and latter with true: this last deploy for example 1 or 2 days later, when you know all your clients have the former version.

you can also use the replace plugin instead the env variable, for example using __CONTROL_APP__. check any example in this repo.

Thanks for all your pointers! I will take a look at them :)

I guess one question to ask for this library (and/or for workbox?) is whether the use case of migrating from autoUpdate to prompt is considered an edge case which needs some deeper understanding of the internals to work yourself out of it, or whether this is something that should be supported "out of the box".

@danielberndt closing this for now since it is not related how this plugin works, feel free open a new issue...