Skip to content

Instantly share code, notes, and snippets.

@meirmsn
Last active April 25, 2020 16:05
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save meirmsn/9b37d6c500654b9a487e0c0a72583ef2 to your computer and use it in GitHub Desktop.
Save meirmsn/9b37d6c500654b9a487e0c0a72583ef2 to your computer and use it in GitHub Desktop.
# To build a prod version of the app, then just need to run:
ionic build --prod && npm run postbuild
#!/usr/bin/env node
// This file when run (i.e: npm run postbuild) will add a hash to these files: main.js, main.css, polyfills.js, vendor.js
// and will update index.html so that the script/link tags request those files with their corresponding hashes
// Based upon source: https://gist.github.com/haydenbr/7df417a8678efc404c820c61b6ffdd24
// Don't forget to: chmod 755 scripts/cache-busting.js
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 wwwRootDir = path.resolve(rootDir, '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);
var jsPolyfillsPath = path.join(buildDir, 'polyfills.js');
var jsPolyfillsFileHash = revHash(fs.readFileSync(jsPolyfillsPath));
var jsPolyfillsNewFileName = `polyfills.${jsPolyfillsFileHash}.js`;
var jsPolyfillsNewPath = path.join(buildDir, jsPolyfillsNewFileName);
var jsPolyfillsNewRelativePath = path.join('build', jsPolyfillsNewFileName);
var jsVendorPath = path.join(buildDir, 'vendor.js');
var jsVendorFileHash = revHash(fs.readFileSync(jsVendorPath));
var jsVendorNewFileName = `vendor.${jsVendorFileHash}.js`;
var jsVendorNewPath = path.join(buildDir, jsVendorNewFileName);
var jsVendorNewRelativePath = path.join('build', jsVendorNewFileName);
// rename main.css to main.[hash].css
fs.renameSync(cssPath, cssNewPath);
// rename main.js to main.[hash].js
fs.renameSync(jsPath, jsNewPath);
// rename polyfills.js to polyfills.[hash].js
fs.renameSync(jsPolyfillsPath, jsPolyfillsNewPath);
// rename vendor.js to vendor.[hash].js
fs.renameSync(jsVendorPath, jsVendorNewPath);
// 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);
$('body script[src="build/polyfills.js"]').attr('src', jsPolyfillsNewRelativePath);
$('body script[src="build/vendor.js"]').attr('src', jsVendorNewRelativePath);
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
// Add the following two lines to src/index.html
<meta http-equiv="Cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
// The above change I'm not sure yet if it is helping or not, but leaving it here in case it's useful
// or others understand it better
# Add these modules to your dev dependencies for cache-busting.js to work
npm i cheerio --save-dev
npm i rev-hash --save-dev
"scripts": {
"postbuild": "./cache-busting.js"
}
// Edit this file: node_modules/@ionic/app-scripts/config/webpack.config.js
// The following change enables the hashing of the modules / chunk files,
// so it works with lazy loading.
//
// Add the following line to add "chunkFilename" key to prodConfig' output dict:
chunkFilename: '[name].[chunkhash].chunk.js',
// So it should look like:
var prodConfig = {
entry: process.env.IONIC_APP_ENTRY_POINT,
output: {
path: '{{BUILD}}',
publicPath: 'build/',
filename: '[name].js',
chunkFilename: '[name].[chunkhash].chunk.js',
devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
},
// (line 14 is the only change: a one line addition)
// Granted this is not the best solution, some problems: you have to remember to add
// this line back everytime you are re-installing packages, or installing them for
// the first time, or updating ionic to the latest version, and probably many more issues
// that are beyond me. But it's somewhat simple and it has worked for my case.
@meirmsn
Copy link
Author

meirmsn commented Nov 14, 2019

Thanks everyone! I'm glad it has been helpful

@startupskateboard
Copy link

Does anyone know how I can make this work with the latest version of Ionic?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment