Nowadays most applications are developed based on large CSS libraries like Bootstrap, Tailwind CSS, etc.. and sometimes multiple frameworks. But your application components are not using all of the styles and it adds more weight to the application performance. This post will explain the Angular post-build process to remove unused CSS and hidden JavaScript files that enhance the application security and definitely improve the app loading time and save the overall bandwidth cost.
GitHub Source
Live Demo
Requirements
- Node Latest
- Angular Cli
ng new angular-post-css
app.component.html
Update the component HTML file
<h1>Welcome to Angular Post Build </h1>
<router-outlet></router-outlet>
<router-outlet></router-outlet>
Run Application
Use the following command to run the application
ng serve
You will find the following output at http://locahost:4200
Install Bootstrap Framework
Execute the following npm command to install the Boostrap and icons.
npm install bootstrap bootstrap-icons
Configure Bootstrap with Application
Go to angular.json and update styles object and include node_modules bootstrap CSS or SCSS path.
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"node_modules/bootstrap/scss/bootstrap.scss",
"node_modules/bootstrap-icons/font/bootstrap-icons.css",
"src/styles.scss"
],
"scripts": []
},
Note: Update outputPath to dist.
Update with Bootstrap Classes
Implemented the HTML with Bootstrap classes.
<div class="container">
<h1><i class="bi bi-robot"></i> Welcome to Angular Post Build </h1>
<div>
<button class="btn btn-success" type="submit"><i class="bi bi-bug-fill"></i> Test Button</button>
</div>
</div>
<router-outlet></router-outlet>
Now you will find the better page design
Build the Project for Production
The following command will generate the production distribution files.
ng build --configuration production
Large CSS file
You will find a finally generated CSS file size(263 KB) here. But the above HTML component is using very minimal Bootstrap classes.
Remove Unused CSS
We are going to implement this with production build process.
PurgeCSS
This tool will analyze JavaScript and HTML file and removes the unused CSS.
npm install purgecss --save-dev
You need following dependancy for executing PurgeCSS command
npm install fs child_process path --save-dev
purgecss.js
Create a external script file, here the following script analyze the dist folder and minimize the CSS file. Create a scripts folder under the project src directory.
const exec = require('child_process').exec;
const fs = require('fs');
const path = require('path');
// find the styles css file
const files = getFilesFromPath('./dist', '.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('./dist/' + f) + 'kb';
var o = { file: f, originalSize: originalSize, newSize: '' };
data.push(o);
}
console.log('Run PurgeCSS...');
exec(
'./node_modules/purgecss/bin/purgecss.js -css dist/*.css --content dist/index.html dist/*.js -o dist/',
function (error, stdout, stderr) {
console.log('PurgeCSS done');
console.log();
for (let d of data) {
// get new file size
const newSize = getFilesizeInKiloBytes('./dist/' + d.file) + 'kb';
d.newSize = newSize;
}
console.table(data);
}
);
function getFilesizeInKiloBytes(filename) {
var stats = fs.statSync(filename);
var fileSizeInBytes = stats.size / 1024;
return fileSizeInBytes.toFixed(2);
}
function getFilesFromPath(dir, extension) {
let files = fs.readdirSync(dir);
return files.filter((e) => path.extname(e).toLowerCase() === extension);
}
package.json
Update the package scripts and include purgecss command with build command.
"scripts": {
"ng": "ng",
"start": "ng serve",
"purgecss": "node ./src/scripts/purgecss.js",
"build": "ng build --configuration production && npm run purgecss",
"watch": "ng build --watch --configuration development",
"test": "ng; test"
},
Build Project
Now the following command will execute the project build with purge css commands.
npm run build
After the application build, this will remove the unused CSS and creates a new small(9KB) CSS file Converted CSS File
Obfuscate JavaScript
This makes your code harder to copy and prevents people from stealing your work. This tool helps you to convert regular JavaScript to a difficult way to read. It enhances security and provides protection for your source code.
Install Javascript Obfuscator
Include javascript-obfuscator plugin in dev dependencies
npm install javascript-obfuscator --save-dev
obfuscate.js
External executable file and analyze the dist files and convert all of the JavaScript file. Copy this file under the application src/scripts folder.
const fs = require("fs");
const path = require("path");
const JavaScriptObfuscator = require("javascript-obfuscator");
const settings = {
compact: true,
};
function obfuscateDir(dirPath) {
let dirents = fs.readdirSync(dirPath, {
encoding: "utf8",
withFileTypes: true,
});
for (let i = 0; i < dirents.length; i++) {
let dirent = dirents[i];
if (dirent.isDirectory()) {
obfuscateDir(path.join(dirPath, dirent.name));
continue;
}
if (path.extname(dirent.name) !== ".js") continue;
const filePath = path.join(dirPath, dirent.name);
const content = fs.readFileSync(filePath, { encoding: "utf8" });
const obfuscator = JavaScriptObfuscator.obfuscate(content, settings);
const obfuscatedCode = obfuscator.getObfuscatedCode();
fs.writeFileSync(filePath, obfuscatedCode, {
encoding: "utf8",
flag: "w+",
});
console.log("🤖 🤖 🤖 Done!");
}
}
obfuscateDir(path.join(__dirname, "../../dist"));
Obfuscate JavaScript File
Copy executable script files under src/scripts directory
Final package.json
Combine all the external scripts and include the post-build command.
"scripts": { },
"ng": "ng",
"start": "ng serve",
"purgecss": "node ./src/scripts/purgecss.js",
"obfuscate": "node ./src/scripts/obfuscate.js",
"postbuild": "npm run purgecss && npm run obfuscate",
"build": "ng build --configuration production && npm run postbuild",
"watch": "ng build --watch --configuration development",
"test": "ng test"
Note: If you are using translated language file, don't include any CSS styles. Purge CSS analyze only JS and HTML files. Angular Multiple Language Support using Internationalization (i18n)
0 comments: