It would be awesome if we could have file revisions to avoid cache issues. I know ionic is designed for mobile platforms but cordova gives us a possibility to add browser platform which can be used for web (and we’re using it). Having static file names for assets like main.js or main.css can be problematic when its up to caching.
I’ve made a workaround with nodejs script that after browser platform build, renames the files by calculating its MD5 hash and updates the references in index.html but it would be great if it could be easier.
In the time Ionic is not suporting it out of the box, i’lve wrote a small node script that calculates files MD5, renames files and replaces their refrences in other files.
Dependency is just a md5-file package to calc the hash.
//file-revision.js:
#!/usr/bin/env node
var md5File = require('md5-file'),
fs = require('fs');
/**
* This script renames files inside platforms/browser/www/ folder and updates their references in html files like index.html
* The mechanism is for improve caching. So file like `main.js` will be renamed to `main.[FILE-MD5-HASH].js` and its references
* in html files will be updated.
*/
var buildFolder = 'platforms/browser/www/';
var assetsFolder = buildFolder + 'build/';
var jsFiles = [
'main',
'kajam'
];
var cssFiles = [
'main'
];
var htmlFilesToUpdate = [
'index.html',
'oauth.html'
];
var replacements = [];
jsFiles.forEach(function (file) {
var hash = md5File.sync(assetsFolder + file + '.js');
renameFile(file + '.js', file + '.' + hash + '.js');
});
cssFiles.forEach(function (file) {
var hash = md5File.sync(assetsFolder + file + '.css');
renameFile(file + '.css', file + '.' + hash + '.css');
});
htmlFilesToUpdate.forEach(function (htmlFile) {
console.log('Update "' + htmlFile + '" with new file revisions.');
console.log('Replacements: ' + JSON.stringify(replacements));
replacements.forEach(function(replacementObject) {
replaceInFile(buildFolder + htmlFile,replacementObject.from, replacementObject.to);
});
});
function renameFile(input, output) {
console.log('Rename "' + input + '" to "' + output + '"');
fs.rename(assetsFolder + input, assetsFolder + output);
if (fs.existsSync(assetsFolder + input + '.map')) {
console.log('Rename "' + input + '.map" to "' + output + '.map"');
fs.rename(assetsFolder + input + '.map', assetsFolder + output + '.map');
}
replacements.push({from: input, to: output})
}
function replaceInFile(file, regex, replacement) {
var fileContents = fs.readFileSync(file, 'utf-8');
fs.writeFileSync(file, fileContents.replace(regex, replacement), 'utf8');
}
After adding and building a browser platform, just run it:
node file-revision.js
This should rename all files that are specified in the script and update references to them.