tooling.report

feature

Asset hash cascading

When JS depends on an asset, and the asset is changed, are the hashes correctly updated?

Person in shorts with blue hair walking left

Introduction

When including hashes in the URLs of non-JavaScript assets, it's often necessary to reference those URLs from JavaScript. When the contents of an asset are changed - an image updated or text content changed - it's hashed URL also changes. If a JavaScript bundle references that asset's URL, it's important that the bundle's hashed URL is also updated, since it must now be compiled with the updated hash of its asset "dependency".

The Test

This test compiles an asset and a JavaScript module containing a reference to it, both configured to produce hashed URLs. The test is run twice to simulate changing the contents of some-asset.txt (replacing the "." with "!").

index.js

import txtUrl from './some-asset.txt';
console.log(txtUrl);

some-asset.txt

This is an asset.

Bundling the above should produce two files with hashes in their names, like bundle.12345.js and some-asset.54321.txt. When the contents of some-asset.txt are changed and the project is rebuilt, the hash must be different in both output files.

Conclusion

browserify

Browseriy supports "importing" assets as hashed asset URLs through the urify-emitter transform. The generated bundles include hashed asset URLs, so when these are passed through gulp-rev-all to apply content-based hashing, any changes to an asset URL cause the corresponding JavaScript bundle's hash to change.

parcel

Parcel supports importing raw assets to obtain their hashed URLs out-of-the box via a the URL constructor.

Changes to assets correctly cause the hash of the bundle with the asset reference to change.

rollup

When an asset is updated and its hashed URL changes, the hash of the JavaScript bundle that references it is not automatically updated.

Plugin authors can work around this using augmentChunkHash in some cases, so the tests provided here pass. However, it seems like a considerable footgun that this isn't taken care of automatically, so this test is marked as 'partial'.

Issues

webpack

When importing assets using new URL, Webpack creates a small intermediary module that exports the hashed asset URL. The intermediary module gets concatenated into bundles alongside any module that imports it. This means that any changes to the hashed URL in a bundle also cause the hashed URL of that bundle to change.