Angular 2 CLI – Extract Hash Value

Hey, all! In this post, I’m just going to quickly show you how you could extract the hash that’s generated using angular 2’s CLI when building with production build flags.

ng build --target=production --environment=prod
ng build --prod --env=prod
ng build --prod

For starters, why does cli add this random string in the generated files? The simple answer is what we call cache-busting. Leaving what cache is, and what it means to cache-bust for you to research on your own. So it’s great and all, but even if you’re using the cli, you’re not necessarily using its index.html file for anything. You might have your own way of inserting these generated files into your application. Which also means you’ll need to know the file name.

So there are 2 ways of going about this. First, which I won’t talk about is, during the build, using the --stats-json option. This outputs a JSON file with all the data you would ever need, including the hash values. Another way, is parsing the index.html file. Go ahead, build for prod. And let’s see a simple way we can parse that file using Node.

var fs = require('fs');
fs.readFile('./dist/index.html', "utf-8", function(err, data) {
    if (err) throw err;

    // Match doesn't support groups, so first do a strict match, then filter further to get the url.
    var inline = content.match(/src="(inline.*?.js)"/g);
    if (inline.length > 0) {
        inline = inline[0].match(/inline.*?.js/g)[0];
    } else {
        inline = '';
        throw new Error('Inline failed to parse');
    }

    // inline is now something like "inline.hash-value.bundle.js".

});

We do the same for the src="(polyfills.*?.js), src="(vendor.*?.js), and src="(main.*?.js). For style, depending on how you went about setting up your configurations, you’d need either the css or the JS file. Example:

    var stylesJS = content.match(/src="styles.*?.js"/g);
    if (null !== stylesJS && stylesJS.length > 0) {
        console.log("Style found for type JS");
        stylesJS = stylesJS[0].match(/styles.*?.js/g)[0];
        _stylesLinkJs = ''
        console.log("Style found for type JS link is: ", _stylesLinkJs);
            
    }

    var stylesCSS = content.match(/href="styles.*?.css"/g);
    if (null !== stylesCSS && stylesCSS.length > 0) {
        console.log("Style found for type CSS");
        stylesCSS = stylesCSS[0].match(/styles.*?.css/g)[0];
        _stylesLinkCss = '';
        console.log("Style found for type CSS link is: ", _stylesLinkCss);
            
    }

Either one of those could be empty. But now you have the full link to all files. Whether it’s through ASP.Net or some other way, you can inject that data. A quick look at how you could write to a cshtml file:

    var _mainLink = '';

    fs.writeFile("/Views/Shared/_AngularHashedMain.cshtml", _mainLink, function(err) {
        if (err) {
            return console.log(err);
        }
        console.log("_AngularHashedMain.cshtml was saved!");
    });

You can repeat that for all files, or put all the inline and vendors into one file. Hopefully, this helps out someone else. The regex is definitely not the greatest, but this is done within split seconds during the build, so it works for me.

I'm a software engineer primarily focusing on frontend work right now, and currently working at Tallie/Nexonia/Certify. Travel, Coding, and Photography is what I live for :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s