Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ionic cache busting
#!/usr/bin/env node
var fs = require('fs'),
path = require('path'),
cheerio = require('cheerio'),
revHash = require('rev-hash');
var rootDir = path.resolve(__dirname, '../');
var wwwRootDir = path.resolve(rootDir, 'platforms', 'browser', 'www');
var buildDir = path.join(wwwRootDir, 'build');
var indexPath = path.join(wwwRootDir, 'index.html');
var cssPath = path.join(buildDir, 'main.css');
var cssFileHash = revHash(fs.readFileSync(cssPath));
var cssNewFileName = `main.${cssFileHash}.css`;
var cssNewPath = path.join(buildDir, cssNewFileName);
var cssNewRelativePath = path.join('build', cssNewFileName);
var jsPath = path.join(buildDir, 'main.js');
var jsFileHash = revHash(fs.readFileSync(jsPath));
var jsNewFileName = `main.${jsFileHash}.js`;
var jsNewPath = path.join(buildDir, jsNewFileName);
var jsNewRelativePath = path.join('build', jsNewFileName);
// rename main.css to main.[hash].css
fs.renameSync(cssPath, cssNewPath);
// rename main.js to main.[hash].js
fs.renameSync(jsPath, jsNewPath);
// update index.html to load main.[hash].css
$ = cheerio.load(fs.readFileSync(indexPath, 'utf-8'));
$('head link[href="build/main.css"]').attr('href', cssNewRelativePath);
$('body script[src="build/main.js"]').attr('src', jsNewRelativePath);
fs.writeFileSync(indexPath, $.html());
# run this command in your terminal to give npm permission to run the cache busting script
chmod 755 ./cache-busting.js
{
"author": "Unboxed Technology",
"homepage": "https://www.unboxedtechnology.com/",
"scripts": {
"build": "ionic cordova build browser --release --prod --no-interactive",
"postbuild": "./cache-busting.js"
}
}
@borodiliz

This comment has been minimized.

Copy link

@borodiliz borodiliz commented Dec 28, 2017

Thanks @haydenbr for saving my time!. Here my version which also hash polyfills.js and vendor.js:

#!/usr/bin/env node

var fs = require('fs'),
        path = require('path'),
        cheerio = require('cheerio'),
        revHash = require('rev-hash');

/**
 *
 * @param string fileName
 * @returns string
 */
function hashFile(file) {

    // Get file name
    var fileName = file.replace(/\.[^/.]+$/, "");
    // Get file extension
    var re = /(?:\.([^.]+))?$/;
    var fileExtension = re.exec(file)[1];

    var filePath = path.join(buildDir, file);
    var fileHash = revHash(fs.readFileSync(filePath));
    var fileNewName = `${fileName}.${fileHash}.${fileExtension}`;
    var fileNewPath = path.join(buildDir, fileNewName);
    var fileNewRelativePath = path.join('build', fileNewName);
    //Rename file
    console.log("cache-busting.js:hashFile:Renaming " + filePath + " to " + fileNewPath);
    fs.renameSync(filePath, fileNewPath);

    return fileNewRelativePath;
}


var rootDir = path.resolve(__dirname, '../');
var wwwRootDir = path.resolve(rootDir, 'www');
var buildDir = path.join(wwwRootDir, 'build');
var indexPath = path.join(wwwRootDir, 'index.html');
$ = cheerio.load(fs.readFileSync(indexPath, 'utf-8'));

$('head link[href="build/main.css"]').attr('href', hashFile('main.css'));
$('body script[src="build/main.js"]').attr('src', hashFile('main.js'));
$('body script[src="build/polyfills.js"]').attr('src', hashFile('polyfills.js'));
$('body script[src="build/vendor.js"]').attr('src', hashFile('vendor.js'));

fs.writeFileSync(indexPath, $.html());
@wvervuurt

This comment has been minimized.

Copy link

@wvervuurt wvervuurt commented Feb 22, 2018

This script is awesome, thanks @haydenbr and @borodiliz!
I changed the console log output of the @borodiliz's version to be a little more readable because I care about stupid things like that ;).

For anyone interested, I changed the console.log line in this hashFile function to

console.log(`${fileName}.${fileExtension} >> ${fileName}.${fileHash}.${fileExtension}`);

@nickwinger

This comment has been minimized.

Copy link

@nickwinger nickwinger commented Mar 24, 2018

how about the lazy loaded pages, e.g. 0.js, 1.js etc. ?

@kirillgroshkov

This comment has been minimized.

Copy link

@kirillgroshkov kirillgroshkov commented Apr 18, 2018

Worked for me!

Good solution for lazy loading is described here: https://gist.github.com/meirmsn/9b37d6c500654b9a487e0c0a72583ef2

@chaityashah

This comment has been minimized.

Copy link

@chaityashah chaityashah commented Mar 19, 2019

I am getting Error as below:

./cache-busting.js

'.' is not recognized as an internal or external command,

Is there any solution ? Or is there anything I am missing?

I run npm run build to build the application.

@omelsoft

This comment has been minimized.

Copy link

@omelsoft omelsoft commented Feb 16, 2020

I am getting Error as below:

./cache-busting.js

'.' is not recognized as an internal or external command,

Is there any solution ? Or is there anything I am missing?

I run npm run build to build the application.

In your package.json file, add "postbuild": "node ./cache-busting.js" after your build scripts like:

"scripts": {
        "start": "ionic-app-scripts serve",
        "clean": "ionic-app-scripts clean",
        "build": "ionic-app-scripts build",
        "postbuild": "node ./cache-busting.js",
        "lint": "ionic-app-scripts lint",
        "docs": "./node_modules/.bin/compodoc -d ./docs/ -p ./tsconfig.json --theme vagrant",
        "serve-docs": "./node_modules/.bin/compodoc -s -d ./docs"
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.