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.