问题
I have an Angular 8 application for which I have had caching problems during deployment of new releases.
Basically I noticed that when using ng build --prod
, the outputHashing
option is set to all
in my angular.json
. Therefore all files generated by ng build
have a content hash in their names, which is great for two reasons:
- the browser can safely long-term cache the files of my application (if the content of the file changes in a new release, the name changes and therefore the file is reloaded by all clients)
- if a file does not change from one release to another, it won't be re-downloaded
(note: index.html is never cached)
So that seems pretty efficient.
Now the problem is that not all files have this cache busting name. The files declared as assets in the angular.json
are just copied "as is" during build. Therefore, if I release a new version of my application, I have no guarantee whatsoever that the clients will use the latest versions of the assets.
These assets includes JSON translation files (used by ngx-translate), images (referenced directly in the templates of the application) as well as other things.
I read a lot about this on Stack Overflow and GitHub but couldn't come with a good enough solution.
I tried using a @angular-builders/custom-webpack:browser
with a custom Webpack config that uses html-loader
and file-loader
to rename the files as well as each reference to them in the source code but that didn't seem to work.
Is it possible to have cache busting names for assets files in an Angular application? If so, what is the recommended approach and how does it work?
回答1:
- You are right, assets are not given a hash.
- And one more noticeable disadvantage for performance is that they add their own script tag to index.html. The bundles that are generated from the main property in the builder options are dependent of that script. So if for some reason this script is delayed (e.g its big asset) then the whole bootstrap is delayed! And maybe this asset script could have bring brought lazy if the bootstrap doesn't depend on it?
I'm curious why that didn't work for you:
I tried using a @angular-builders/custom-webpack:browser with a custom Webpack config that uses html-loader and file-loader to rename the files as well as each reference to them in the source code but that didn't seem to work.
I'll be happy to look at this in another question. This is the approach we are taken.
来源:https://stackoverflow.com/questions/61607242/asset-caching-problems-in-angular-application