Repository
This will launch the app on localhost at port 5000. You would still see the page running as before. Open the developer tool, click the Application tab and select Service Workers. You should see a registered service worker: The huge red box highlights the status of the registered service worker. As you can see, the status shows it's active.
New Feature
This is part feature, part bug fix, and part mini tutorial, and involves Progressive Web Apps, Workbox, and Service Workers, integrating into the TokenBB project, which uses the Vue.js framework.
The issue initially as stated was as follows. Before this change, there was code in place that used the cli-plugin-pwa package to generate a workbox service worker responsible for handling precaching of assets, as documented here. In our case, every time a production build is complete, it generates a different service worker. Then on the client side, when the page is loaded, it detects a new version of the service worker is available, installs the service worker in the background. The intent is then that it can prompt the user to refresh to apply the new version of the website.
However, this wasn't happening. We use register-service-worker npm package that manages the life-cycle of the service worker. In our code here you'll see a callback detecting when a service worker is found, applied, and updated in
updated
, and output the log New content is available; please refresh.
, but refreshing the page did not apply the new content.Turns out that is because of details concerning the Service Worker Lifecycle. Essentially, when a new service update worker is available, it gets installed in the background, but it does not apply until the old service worker is cleaned up. This requires all tabs containing that service worker to be closed down. Specifically, refreshing did not actually accomplish that task, as it does not count as a full close of the tab.
The Workbox Guides have a recipe for it, but it is very verbose. Thankfully the register-service-worker npm condenses a lot of this work. As you'll see in the next section, the task was managed in very few lines, but understanding how all the pieces worked together took me quite a long time.
Anyway, now we have a nice little refresh button
where pressing it actually updates to the new service worker and new version of the website. Yay.
The upshot here is that it gets rid of the confusion when a new update has gone out but people refreshing the page do not see the update (which was happening up until now :) ). Definitely of interest to @reggaemuffin and @thecryptodrive.
Code Details
You can find the merged pull request with the highlighted changes here: https://github.com/BuildTeamDev/tokenbb-web-client/pull/28/files
The solution has the following ingredients:
- Notification with user 'refresh' link to trigger the force install of the new service worker.
- Addition to service worker to detect the trigger and activate.
- Set up trigger to reload the page once the new service worker is applied.
This file has the changes for step (3), the reload signal, and step (1), the trigger. Note that it is done via a
postMessage
to the waiting service worker. The nice part about the register-service-worker package is that it encapsulates everything we need to detect the event that the new service worker is ready and waiting, and get access to the waiting service worker to send the message.The 'skipWaiting' message gets picked up in this file and simply calls 'skipWaiting' on the service worker. This allows the waiting service worker to activate immediately and kick out the old service worker. This extra JS is passed in as an option to workbox, which we added as a static JS asset to be fetched by the service worker code (For Vue, the build preserves all files in the
public
directory into its bundle).This issue gave a hint for how to augment the service worker generated by workbox and cli-plugin-pwa.
And that's it! It took a long while at first because while chasing around the documentation I didn't realize that I needed to augment the service worker to catch the postMessage (thought it was in the generated service worker). Seems like there's some discussion about that in that referenced issue above.
As usual, let me know if you have any feedback/questions below.
GitHub Account
Posted by1 year ago
Archived
I started a project using the Vue CLI (v3) and added the option for the PWA plugin. Out of the box the service worker that is generated does not do enough for what I will ultimately need my service worker to do.
I changed the vue.config.js to point to a new custom service worker with the 'pwa' option. (Setting pwa.workboxPluginMode to 'InjectManifest' and pwa.workboxOptions.swSrc to 'path-to-custom-sw.js') I am able to get the custom service worker to output to my dist folder but not get recognized by the application when it runs. I figured it was because of how the registerServiceWorker.js file is referencing the old service-worker.js (even though i thought workbox automatically would output my service worker to be named service-worker.js)
So I tried to change it to point to my new custom service worker. In the registerServiceWorker.js file but it did not register correctly when I ran the app.
I am probably doing something wrong but I couldn't find a lot of resources on how to add a custom service worker to a new PWA plugin vue project. If I can't get it to work I think I may just use the previous cli v2 PWA template instead.
tl;dr - I am trying to use a custom service worker in a project created by the v3 cli with pwa plugin and failing miserably. help!
1 comment