// orignal author @dylanvdmerwe - https://dev.to/dylanvdmerwe/reduce-angular-style-size-using-purgecss-to-remove-unused-styles-3b2k const exec = require("child_process").exec; const fs = require("fs"); const path = require("path"); const chalk = require("chalk"); function removeUnusedCSS() { var pathPrefix = process.argv.slice(2)[0]; // find the styles css file const files = getAllFiles(`./${pathPrefix}/`, ".css"); let data = []; if (!files && files.length <= 0) { console.log("cannot find style files to purge"); return; } for (let f of files) { // get original file size const originalSize = getFilesizeInKiloBytes(f) + "kb"; var o = { file: f, originalSize: originalSize, newSize: "" }; data.push(o); } console.log("Run PurgeCSS..."); let cmd = []; for (let d of data) { cmd.push( `npx purgecss -css ${d.file} --content ${pathPrefix}/index.html ${pathPrefix}/*.js -o ${d.file}` ); } cmd = cmd.join(" & "); exec(cmd, function (error, stdout, stderr) { console.log(`${chalk.greenBright("✔")} PurgeCSS done`); console.log(); for (let d of data) { // get new file size const newSize = getFilesizeInKiloBytes(d.file) + "kb"; d.newSize = newSize; } const fileLength = data.map((x) => x.file.length).sort((a, b) => b - a)[0]; const originalSizeLength = data .map((x) => x.originalSize.length) .sort((a, b) => b - a)[0]; const newSizeLength = data .map((x) => x.newSize.length) .sort((a, b) => b - a)[0]; const fileDesciption = padString("Resized Files", fileLength, false); const originalSizeDesciption = padString( "Original Size", originalSizeLength, true ); const newSizeDesciption = padString("New Size", newSizeLength, true); tableHeader(fileDesciption, originalSizeDesciption, newSizeDesciption); for (let d of data) { const file = padString(d.file, fileDesciption.length, false); const originalSize = padString( d.originalSize, originalSizeDesciption.length, true ); const newSize = padString(d.newSize, newSizeDesciption.length, true); tableRow(file, originalSize, newSize); } }); } function tableHeader(a, b, c) { console.log(chalk.bold(a) + " | " + chalk.bold(b) + " | " + chalk.bold(c)); } function tableRow(a, b, c) { console.log(chalk.greenBright(a) + " | " + b + " | " + chalk.cyanBright(c)); } function padString(str, padSize, padStart) { var size = padSize - str.length + 1; if (size < 0) { size = 0; } var padding = new Array(size).join(" "); if (padStart) { return padding + str; } return str + padding; } function getFilesizeInKiloBytes(filename) { var stats = fs.statSync(filename); var fileSizeInBytes = stats.size / 1024; return fileSizeInBytes.toFixed(2); } function getAllFiles(dir, extension, arrayOfFiles) { const files = fs.readdirSync(dir); arrayOfFiles = arrayOfFiles || []; files.forEach((file) => { if (fs.statSync(dir + "/" + file).isDirectory()) { arrayOfFiles = getAllFiles(dir + "/" + file, extension, arrayOfFiles); } else { if (file.endsWith(extension)) { arrayOfFiles.push(path.join(dir, "/", file)); } } }); return arrayOfFiles; } // Start Post Build removeUnusedCSS();