I have an angular application. In deployment pipeline we are using "ng build --prod" command to build application. This command generates different hashcode for build files any time we make code changes. However we are seeing issue that user has to clear browser cache to see new functionalities after deployment. Any suggest why cache clear is required even though build file names are different on deployment.
CodePudding user response:
When you are building the application using ng build, you should use the following flag:
--outputHashing=all
This is to enable cache-busting.
Cache-busting solves the browser caching issue by using a unique file version identifier to tell the browser that a new version of the file is available. Therefore the browser doesn’t retrieve the old file from cache but rather makes a request to the origin server for the new file.
Threfore, one way to do it would be to run this:
Example ( older versions)
ng build --prod --aot --output-hashing=all
Below are the options you can pass in --output-hashing
none: no hashing performed media: only add hashes to files processed via [url|file]-loaders bundles: only add hashes to the output bundles all: add hashes to both media and bundles Updates
For the newer version of angular ( for example Angular 10) the command is now updated :
ng build --prod --aot --outputHashing=all
You may read more about the build options flags over here. https://angular.io/cli/build
If you do not wish to append the flags when you run ng build, you should set it on your configurations at the angular.json file.
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
.
.
.
}
}
CodePudding user response:
Sadly, it's not trivial and a real struggle.
To optimize load times there are several caching layers (browser, server, etc.) and to work around that it's not enough to hash your js files.
Your users are likely to get a cached version of your app, to which the index.html
file still points to the old references of the JS files. Even if you hash the files, you are not invalidating the user's browser cache and hence still attempting to get the old application.
Well, nice theory but we want solutions.
In order to work around that you should:
- Hash your source files, @Priyanka pointed out on how to achieve that
- Send cache headers from your server hinting your browser to NOT cache the app. Ever.
Alternative you may avoid doing 2 by setting some <meta>
tags on the index.html
file. BEWARE that if the server served the index.html using some cache headers, the browser will use THOSE instead of the directives you gave in the <meta>
tags
(for 2) Which are the magic headers for that?
// HTTP 1.1. Standard
Cache-Control: no-cache, no-store, must-revalidate
// HTTP 1.0 Standard
Pragma: no-cache
// Proxies
Expires: 0
How to set that on your webserver depends on what setup you have… Is it an Nginx? an IIS? I can't tell what code to use for your server without knowing that.
This won't fix the problem immediately because your user's browser may have not yet invalidated the previous cache. So as soon as it invalidates it and receives the new headers you'll be good.