How To: Update the Application Without Rebuilding

PWA uses ServiceWorkers to cache data to track file changes by revision. When changing any file, you need to:

  • make sure it is in the precache manifest;
  • get a hash from the content of that file;
  • update the revision in precache manifest.

The manifest is located in the service-worker.js file - this is minified JS code. So, changing the revision there is not the easiest thing.

The manifest is in a variable:

const A={precacheManifest:[{...}, {...}]}

where A can vary. Therefore, a fixed property was created not to change the uglify rules for the whole project.

You can get it out with a regular expression by precacheManifest: from [ to ]. Look at the example file below.

The result would be the string like:

{'revision':'063fb803d113f1dcdbb3540a4bf6f15d','url':'/063fb803d113f1dcdbb3540a4bf6f15d.png'},{'revision':'8038390b8f2ddcee0978f389ee210ef7','url':'/8038390b8f2ddcee0978f389ee210ef7.png'},{'revision':'3012fcf13aed1c0efca2b9286b619fa8','url':'/assets/css/Catalog.1.5b1f948c9c93be6e2a30.css'},{'revision':'7fe135b646fbb525237338069ebdb906','url':'/assets/css/Catalog.1.5b1f948c9c93be6e2a30.css.map'},{'revision':'334110ce052816ef3e0a60b386ead417','url':'/assets/css/app.2.5b1f948c9c93be6e2a30.css'},{'revision':'87326d87b0bb65b06e2f009e5c17bb9d','url':'/assets/css/app.2.5b1f948c9c93be6e2a30.css.map'},{'revision':'d41d8cd98f00b204e9800998ecf8427e','url':'/assets/css/custom_style.css'},{'revision':'3d8223fd418b996caf0d98003e5c287e','url':'/assets/css/vendors.0.5b1f948c9c93be6e2a30.css'},{'revision':'da58bbcaebfe888904d4a4327eeefea7','url':'/assets/css/vendors.0.5b1f948c9c93be6e2a30.css.map'},{'revision':'3127475e5fd50c717d8284a6a5c692ae','url':'/assets/extensions/loader.js'},{'revision':'2627d28fb8620079e6aff738be9a838e','url':'/assets/js/4.5b1f948c9c93be6e2a30.bundle.js'},{'revision':'463785ce2c4ae7b132e4e74193f63480','url':'/assets/js/4.5b1f948c9c93be6e2a30.bundle.js.map'},{'revision':'688238103f0c4e05c678cfc24a8c51ff','url':'/assets/js/Catalog.5b1f948c9c93be6e2a30.bundle.js'},{'revision':'026b8c7dc6814020c9e4f585ceb8c799','url':'/assets/js/Catalog.5b1f948c9c93be6e2a30.bundle.js.map'},{'revision':'1253abdd273e63559bd3a6ac7ca09487','url':'/assets/js/app.5b1f948c9c93be6e2a30.bundle.js'},{'revision':'27f90e530b6a665eb135fd905cfb9f39','url':'/assets/js/app.5b1f948c9c93be6e2a30.bundle.js.map'}

A possible variant of how to parse a string: replace ‘ with “ and split the string into an array line by line to get an array of strings, each of them is parsed as JSON.

Further, let’s consider that we have the names of the files that were changed during the update. Find these files in the resulting array by the file name and change the revision in the found object.

A new revision is created with the following logic:

(string) => {
  const md5 = crypto.createHash('md5');
  md5.update(string);
  return md5.digest('hex');
}

So, an encryptor is created using the md5 algorithm: we send the string (file content) and get the result as a cache string.

After that, collect the array again into a string and replace it in the original service-worker.js.