Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is angular-cli's --output-hashing always supposed to work with lazily loaded modules?

I thought I have been successfully cache busting with angular-cli's --output-hashing option set to all to ensure users get the latest chunks/updates. I realized this isn't always working for lazily-loaded modules.

If I make changes only to a lazily-loaded module + build + deploy to IIS, AND go to a URL that belongs to the lazily-loaded module, then I get the latest changes as expected.

However, if I close and re-open the browser and go to a URL that does not belong to the lazily-loaded module, and then click to a link that takes me to the lazily-loaded module, the latest changes are not observed.

It's almost as if browser is assuming nothing is changed whenever I enter the app from a module that hasn't changed, and doesn't pick up the new chunk later when I visit the module that is changed.

Even stranger, when I tried to replicate the issue to provide some screenshots, the issue went away.

Has anyone else experienced inconsistency with cache busting using output-hashing?

Edit:

After investigating some more, it turns out that if I go to the landing page of my site [IP address]:[port], then the index.html comes from the cache.

Instead, if I go to any other route [IP address]:[port]/[route], then the index.html comes from the server.

Since index.html points to inline.(hash).bundle.js, which in return points to lazily-loaded modules, getting the old copy of index.html results in getting old versions of inline.js and other modules.

I tried to add <meta http-equiv="expires" content="0" /> to index.html and cleared browser cache, and still got the file from cache.

I also tried adding a section into web.config, but this did not work either.

How to ensure index.html always comes from the server?

enter image description here

like image 602
Uğur Dinç Avatar asked Mar 13 '18 23:03

Uğur Dinç


1 Answers

Your answer can be found in this SO related question, which outlines how to set up IIS to set the cache settings for the index.html file: How to disable caching of single page application HTML file served through IIS?

Additionally based on the Mozilla Docs, you should set the Cache-Control header to this: no-cache, no-store, must-revalidate

As for the cause of this issue, when Angular is generating the output bundle, it will create JS filenames that will uniquely identify the current version of that file if told to use output hashing (i.e. they create a hash of the file contents and include this in the filename so that browsers do not serve up the cached version of these updated files: js-filename.[hash of content].js instead of just js-filename.js). The problem with this is that the browsers will also serve up the cached version of the index.html file that Angular generates, which will point to the old version of the JS files.

To resolve this issue, you must set up your web server to set the appropriate Cache-Control setting (outlined above) on the index.html file so that the browser never caches this file.

like image 130
Daniel W Strimpel Avatar answered Sep 29 '22 03:09

Daniel W Strimpel