Angular-cli: --output-hashing doesn't work for media files of type (.png, .jpg, .gif .. etc)

Created on 24 Jan 2017  ยท  12Comments  ยท  Source: angular/angular-cli

Versions / Env:

angular-cli: 1.0.0-beta.26
node: 6.0.0
os: darwin x64 (macOS - El Capitan)

Repro steps.

  1. Upgrade to 1.0.0-beta.26 (as per)
  2. Verify --output-hashing is available. # ng build -h
  3. Build a production version. # ng build --prod --output-hashing=all
  4. Verify that all images are hashed

The log given by the failure.

The content of the dist/ directory is as below: Notice that the images are not hashed

dist/
โ”œโ”€โ”€ assets
โ”‚ย ย  โ”œโ”€โ”€ 404.html
โ”‚ย ย  โ”œโ”€โ”€ css
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ loading.css
โ”‚ย ย  โ”œโ”€โ”€ icon
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ favicon.ico
โ”‚ย ย  โ”œโ”€โ”€ img
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ logo
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€logo.png
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ misc
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ search.png
โ”‚ย ย  โ””โ”€โ”€ robots.txt
โ”œโ”€โ”€ fontawesome-webfont.674f50d287a8c48dc19b.eot
โ”œโ”€โ”€ fontawesome-webfont.912ec66d7572ff821749.svg
โ”œโ”€โ”€ fontawesome-webfont.af7ae505a9eed503f8b8.woff2
โ”œโ”€โ”€ fontawesome-webfont.b06871f281fee6b241d6.ttf
โ”œโ”€โ”€ fontawesome-webfont.fee66e712a8a08eef580.woff
โ”œโ”€โ”€ index.html
โ”œโ”€โ”€ inline.67a2fb6cd14ba4fc7671.bundle.js
โ”œโ”€โ”€ main.fdd9bda558d52de42c5f.bundle.js
โ”œโ”€โ”€ main.fdd9bda558d52de42c5f.bundle.js.gz
โ”œโ”€โ”€ scripts.21eca2c64fde6754ea61.bundle.js
โ”œโ”€โ”€ scripts.21eca2c64fde6754ea61.bundle.js.gz
โ”œโ”€โ”€ styles.0a0cdafd30d257765ef7.bundle.css
โ”œโ”€โ”€ styles.0a0cdafd30d257765ef7.bundle.css.gz
โ”œโ”€โ”€ styles.918490a25cf8dcdee0aa.bundle.js.gz
โ”œโ”€โ”€ vendor.7269c21a09875bc3c8ee.bundle.js
โ””โ”€โ”€ vendor.7269c21a09875bc3c8ee.bundle.js.gz

More info

Please note that search.png and logo.png are NOT hashed. Also verified that hash is NOT passed into the image url as a param. (e.g. /url/image.png?hash)

Desired behavior

  1. Option to pass or configure extensions of file types where hashing is desired
  2. Option to include hash in file name
  3. Option to cache bust via url param (?hash)

Note

In this example the --output-hashing=all has been passed in explicitly even though docs indicate that all is a default value for --prod. All combinations & permutations of with/without --output-hashing was attempted without a +ve result.

Most helpful comment

Can you please suggest a workaround as to how to cache media files referenced from templates?
Are there any recommended best practices for angular-cli users?

edit:

Files within your assets are not processed by the build process (just copied). As a result, their use, if any, (and location of use) cannot be determined.

@clydin I understand what you say, however the issue described by @un33k remains very relevant and it would be worth suggesting a workaround or addressing this issue somehow.

All 12 comments

Files within your assets are not processed by the build process (just copied). As a result, their use, if any, (and location of use) cannot be determined.

@clydin - The fonts are handled correctly and if they are hashed the references to the newly hashed font files are also updated. The code that handles the images seems to be similar to that of the font files. The only difference here is that the fonts are copied at the index.html level and the images are in the assets directory.

So, would it be correct to assume that if let's say a logo.png is placed at the index.html level of the dist/ directory, then it would be found and properly hashed and the references to that file are also updated?

Any reference to a document that better explains both usage & limitations of output-hashing is much appreciated.

One possible approach would be to use --output-hashing=none, and then wrap ng-cli in gulp to use gulp-hash to properly hash all files & their reference in the dist directory, post compilation. (not pretty, but will work)

Files referenced from within component templates and stylesheets are not analyzed or processed. This is why they needed to be placed within the project's assets; which is copied to the output at build time.
Handling of component stylesheets will most likely be added in the future.

Closing as answered by @clydin.

Can you please suggest a workaround as to how to cache media files referenced from templates?
Are there any recommended best practices for angular-cli users?

edit:

Files within your assets are not processed by the build process (just copied). As a result, their use, if any, (and location of use) cannot be determined.

@clydin I understand what you say, however the issue described by @un33k remains very relevant and it would be worth suggesting a workaround or addressing this issue somehow.

Any updates on this?

Wouldn't it be, for most Cases, enough to append a GET-Style parameter to the URL (ie. transform logo.png to logo.png?1f56e9bc)? This would allow the filename to stay the same and Components, that need to dynamicly reference these files to continue working.

Appending the asset hash could be controlled with a template function which could read a hash which has been computed for this file at build-time (ie. <img src="{{ assetHash('assets/logo.png') }}">). This would allow a clear approach for opting-in to asset hashing without changing existing applications.

A similar approach could be taken for .less/.css-Files.

@MaZderMind How do you do this for images in css files?

@un33k I'm writing from a very high perspective: I do not know which parsers and filters are actually applied onto which file type by angular and/or webpackt. But I do know that angular already supports pre-processing css-files with less if you just name them accordingly and I do know that a preprocessor similar to less could be used to implement a similar function for css (ie. background-image: assetHash('assets/logo.png');.

What I want to point out is, that by appending a GET-Parameter instead of renaming the file, the Cache-Breaking becomes a function that can be implemented at-runtime and client-side and that can have a nice fall-forward behavior, if an url is constructed at runtime for which, at build-time, no hash-code was calculated or if a resource is accessed externally.

This could be a golden path out of the dilemma explained, that traditional output-hashing will not work for dynamic content (ie templates), if the only use is to break caches - which is probably the 99% use for this feature.

At the moment all relative paths to assets from components' sass stylesheets are hashed and moved to dist/ root dir.
Unfortunately, when there's an absolute path to an asset, it's not hashed at all and not moved to the root dist dir (dir tree is kept). I think at least it should be configurable.

After updating to Angular 7, Cli 7 I notice all assets that are with relative URLs inside the .scss files are copied to dist root with hashing and their URL in the .scss is replaced with the new hash and path.

The other assets that are used in .html (example <img src="/assets/image.jpg" />) components still points to the dist/assets folder.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings