Reputation: 2309
I'm using grunt filerev
task to add cachebusters to files when their content changes. usemin
task to replace the relevant file path with their revved versions where they are referred. Everything is setup well and they are working as expected / written in their documentation.
I'll try to explain the issue now:
This is an Angular JS project where the simplified structure is somewhat like this:
a.html -> b.js -> c.html (partial)
Here a.html refers to b.js and b.js loads c.html as partial. The server is set to cache all these assets so cachebuster strings become important.
When I run grunt build
to execute filerev
and then usemin
, it renames c.html
to c.[md5_hash_of_c].html
, b.js
to b.[md5_hash_of_b].js
and a.html
to a.[md5_hash_of_a].html
. After this it updates the reference line in b.js
for c.html
to c.[md5_hash_of_c].html
. Similarly it updates a.html
as well. This means that when the hashes were calculated, these files still had the unrevved version of other files referenced. As a result, when content of c.html
changes, it updates its reference in b.js
but doesn't update the name of b.js
to reflect this change.
This defeats the very purpose of getting cache-busters in the file names. Because now browser has b.[md5_hash_of_b].js
and a.[md5_hahs_of_a].html
cached, the call for updated c.[md5_hash_of_c].html
fails.
I was thinking that in the angular world and elsewhere as well, it should be a very standard practice, but couldn't see it discussed in detail anywhere. I'm looking for a workflow that can solve this issue.
Upvotes: 2
Views: 950
Reputation: 2309
Found this issue discussed at three different places. The third link is closest to the solution.
I finally ended up using vermin
as a replacement task for filerev
and usemin
which internally executes both the tasks repeatedly until the filenames stop changing. It is shared as a gist here: https://gist.github.com/markrian/aa185c5ec66232a38a68
From gist comments:
/**
* Vermin completely manages the running of the filerev and usemin tasks, so
* that assets that reference other assets are correctly hashed after their
* referenced assets are spliced in by usemin.
*
* Vermin also makes various assumptions about how filerev and usemin are set
* up. For instance, it assumes that usemin runs immediately after filerev,
* that filerev renames files in-place, and that usemin relies on
* `grunt.filerev.summary`, as prepared by filerev (which vermin manipulates).
* There may be other implicit assumptions that haven't been identified yet.
*
* Because grunt tasks can only be inserted into the task stack, to be run
* sequentially, vermin recursively adds filerev, usemin and itself to the
* stack to do its work. It maintains its state on the grunt object, and reads
* that on each run to determine where in the process it is.
*/
Upvotes: 1