Angular PWA.
Before explaining the error, I have to specify :
Globally, inside our CI : Build (ngsw.json is generated) -> overriding appsettings.json -> deploy. Yes, appsettings is overidded after building (so, after ngsw.json
generation). But, before or after such a generation : appsettings.json content is the same: the generated hash has the right/same value between each deployment. Also, such a story's working locally without any issues (build -> change appsettings.json content -> serve).
Our ngsw-config.json
looks like this :
{
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/appsettings.json", // The added line
"/manifest.webmanifest",
"/*.css",
"/*.js"
]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**",
"/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"
]
}
}
]
}
After each deployment (made by our CI), we faced with this error :
Failed to install app version '30ba317c7d27a544efb0c7eb47653aa0fa664fb9'
Error: Hash mismatch (cacheBustedFetchFromNetwork): https://....../appsettings.json: expected 92e837ce30053ba552fcf37c8b34b5d1b1f5f06e, got 9756c02e19847ca03c3cf2d677c65e0a4e9665ef (after cache busting)
at PrefetchAssetGroup.cacheBustedFetchFromNetwork (https://....../ngsw-worker.js:474:21)
at async PrefetchAssetGroup.fetchFromNetwork (https://....../ngsw-worker.js:449:19)
at async PrefetchAssetGroup.fetchAndCacheOnce (https://....../ngsw-worker.js:428:21)
It seems service worker found a wrong hash for appsettings.
However, when the app's checking an update, the resulting ngsw.json
file is correct (we compared with the latest deployed files in our server) : we didn't find the hash that the service worker got (9756c02e19847ca03c3cf2d677c65e0a4e9665ef
). Once again : no hash issue locally, even after editing appsettings.
Of course, there is something we don't understand. Inside the Angular documentation, the "hashed content" part's saying :
If a particular file fails validation, the Angular service worker attempts to re-fetch the content using a "cache-busting" URL parameter to prevent browser or intermediate caching.
What is behind this "validation" ? Is there a "rehash" operation somewhere (which would explain this unknown hash we got) ? We didn't find any explanation about this. If its the case, that doesn't explain why such a story's working locally. As we understood (if we're not goats...), the only "hashing" process is during "ng build"... but maybe we're wrong.
Hashing happens in two occasions:
ng-build
An algorithm will compute the hash of each file based on the file content. This happens during the build process.
Service Worker will first fetch ngsw.json
file to see if a new version exists. If yes, it computes the hash of each file again locally and checks if it matches the hash present in ngsw.json
file.
If at least one hash does not match the hash in ngsw.json
file, it will throw hash-mismatch
error, and the latest version of the app will not be activated.
As you already said, you are applying post-processing, so that is probably the reason for hash-mismatch
error. However, the hash-mismatch
issue can occur for several reasons:
Post-processing after production build: If any post-processing is done on a file after the production build has generated the ngsw.json file, it can result in a hash mismatch when the Service Worker computes it. To avoid this issue, be sure to avoid any post-processing after the production build is generated, such as changing API keys in the index.html file.
Middle layer of caching data: If a middle layer of caching data is present between the client and the server, such as Nginx, it can cause a hash mismatch with the Service Worker.
Deploying the application with Git: When deploying the application with Git using a post-receive git hook, line endings can be replaced by default, causing the files on the server to differ from the original ones, resulting in a hash mismatch.
Serving files through CDN: CDN can apply different optimizations on the files, such as minification or compression, which can change the hash value for these files and result in a hash mismatch for the Service Worker.
I wrote about all of this in my blog, so you can check the article for more details.