Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
un33k opened this issue Jan 24, 2017 · 12 comments
Closed

Comments

@un33k
Copy link

un33k commented Jan 24, 2017

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.

@clydin
Copy link
Member

clydin commented Jan 24, 2017

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.

@un33k
Copy link
Author

un33k commented Jan 24, 2017

@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)

@clydin
Copy link
Member

clydin commented Jan 24, 2017

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.

@filipesilva
Copy link
Contributor

Closing as answered by @clydin.

@balteo
Copy link

balteo commented May 6, 2017

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.

@alexzaytsev-newsroomly
Copy link

Any updates on this?

@MaZderMind
Copy link

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.

@un33k
Copy link
Author

un33k commented May 8, 2018

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

@MaZderMind
Copy link

MaZderMind commented May 8, 2018

@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.

@archasek
Copy link

archasek commented May 14, 2018

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.

@albanx
Copy link

albanx commented Oct 20, 2018

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.

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants