Search code examples
javascriptangulartypescriptwebpackwebpack-file-loader

How to get file hash name in Angular?


In Angular 4 I've used Webpack's (or even File-loader's) require method to get Image hash name:

const versionedName = require('assets/images/icn-copy.svg');

It returns something like "assets/images/icn-copy.435435fj5435f345345f435f435f345f.svg" - hashed file name. And I could use it for request to server. But after migration to Angular 6 require function started returning object with property "default" that contains not hashed name.

How can I get hashed name in Angular 6 and later?

Update: I've noticed that images after migration are not hashed at all now. It may be the reason. For example

.loader {
    background-image: url('assets/images/spinner.svg');
...
}

results in just spinner.svg in the root instead of spinner.214312fe21fe412f4ef.svg

Update 2: As the issue is solved now, I would appreciate to hear about better way to bypass caching for images though. require() is definitely not the best way. It is not about images from assets. It is about requested ones. For example:

this.http.get('assets/images/spinner.svg') // will be cached
this.http.get('assets/images/spinner.214312fe21fe412f4ef.svg') // will NOT be cached.

Solution

  • The issue was that starting from Angular 6 the hashing is disabled by default. Adding flag --output-hashing=all solved the issue. It is good to mention, that In Typescript 2.7 now allowed default imports to CommonJS/AMD/UMD (https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-from-commonjs-modules-with---esmoduleinterop). It means that require() now returns not string with full file name but object with property default containing this string. Instead of

    icn-copy.435435fj5435f345345f435f435f345f.svg
    

    now:

    {
        default: "icn-copy.435435fj5435f345345f435f435f345f.svg"
    }
    

    But I still need better solution! (look update 2)