Himanshu Mishra
Posted on
#node #obfuscate #javascript #security
Obfuscation is the process of making your code unclear and unreadable to humans. This adds a level of security to source code specially in web world were source code is readily available. Minification is the process of removing unnecessary data present in code resulting in smaller file sizes and faster loading. In this tutorial we will focus on making a simple build system which detects every javascript file in our source code to obfuscate and minify.
Prerequisites
To follow this tutorial you need basic knowledge of Javascript and Nodejs. We will use javascript-obfuscator to obfuscate and minify code.
Let's go...
Installation
We will only use one external library javascript-obfuscator which can be installed as a dev dependency.
npm install --save-dev javascript-obfuscator
Imports & Folders
In total we need three libraries - fs, path and javascript-obfuscator.
const Fs = require('fs');const Path = require('path');const JavaScriptObfuscator = require('javascript-obfuscator');
The source code will be kept in src folder and final build files will be generated in build folder.
const src = Path.join(__dirname, '/src/');const build = Path.join(__dirname, '/build/');
Read directories
All the directories will be read recursively and find javascript files which will be than obfuscated and minified. To read files we will use fs module.
function readDirectory(dirPath){ Fs.readdir(dirPath, (err, files) => { if(err) { console.error("Could not list directory.", err); process.exit(1); } files.forEach((file, index) => // loop through every file { let path = Path.join(dirPath, file); console.log(path); }); });}
This will give us path of every file and folder in the provided directory. But we need to read differentiate between files and directories and further read the directories found. This can be done through stat
function provided by fs.
Fs.stat(path, (err, stat) => { if(err) { console.log("error in stating file.", err); return; } if(stat.isFile()) { console.log(`${path} is a file`); } else if(stat.isDirectory()) { console.log(`${path} is a folder`); readDirectory(path); // Further read the folder. }});
Copy files and directories from src to build directory
Now this is perfect time that we start copying all the files found in src to build directory. While copying we will simultaneously also create absent directories present in src.
if(stat.isFile()){ const newPath = path.replace(src, build); // Replace src path with build path. Fs.copyFileSync(path, newPath); // Copy file from old path in src to new path in build. if(newPath.endsWith(".js")) // Check if it is javascript file. { obfuscate(newPath); // Obfuscate copied file in build folder. }}else if(stat.isDirectory()){ var newDir = path.replace(src, build); // Replace src path with build path. if (!Fs.existsSync(newDir)) // Check if directory exists or not. { Fs.mkdirSync(newDir); // Create new directory. } readDirectory(path); // Further read the folder.}
Obfuscation and Minification
Finally, javascript file found will be obfuscated and minified. To do so, we will use JavaScriptObfuscator.obfuscate
function which takes code as first argument and a config object as second.
function obfuscate(filePath){ const content = Fs.readFileSync(filePath).toString(); // Read the files content. var result = JavaScriptObfuscator.obfuscate(content, { // Config for obfuscation compact: true, // Set true to enable minification controlFlowFlattening: true, target: 'browser' } ); // Generated minified and obfuscated code Fs.writeFileSync(filePath, result.getObfuscatedCode()); // Write obfuscted and minified code generated back to file.}
You can read more about the config options here.
Finally...
Here is the full code
const Fs = require('fs');const Path = require('path');const JavaScriptObfuscator = require('javascript-obfuscator');const src = Path.join(__dirname, '/src/');const build = Path.join(__dirname, '/build/');readDirectory(src); // Start reading with src directory.function readDirectory(dirPath){ Fs.readdir(dirPath, (err, files) => { if(err) { console.error("Could not list directory.", err); process.exit(1); } files.forEach((file, index) => // loop through every file { let path = Path.join(dirPath, file); Fs.stat(path, (err, stat) => { if(err) { console.log("error in stating file.", err); return; } if(stat.isFile()) { const newPath = path.replace(src, build); // Replace src path with build path. Fs.copyFileSync(path, newPath); // Copy file from old path in src to new path in build. if(newPath.endsWith(".js")) // Check if it is javascript file. { obfuscate(newPath); // Obfuscate copied file in build folder. } } else if(stat.isDirectory()) { var newDir = path.replace(src, build); // Replace src path with build path. if (!Fs.existsSync(newDir)) // Check if directory exists or not. { Fs.mkdirSync(newDir); // Create new directory. } readDirectory(path); // Further read the folder. } }); }); });}function obfuscate(filePath){ const content = Fs.readFileSync(filePath).toString(); // Read the files content. var result = JavaScriptObfuscator.obfuscate(content, { // Config for obfuscation compact: true, // Set true to enable minification controlFlowFlattening: true, target: 'browser' } ); // Generated minified and obfuscated code Fs.writeFileSync(filePath, result.getObfuscatedCode()); // Write obfuscted and minified code generated back to file.}
Hurray!!! you made till end.
I hope you would have found it useful. If yes, than show some love by commenting and sharing.
Thanks for reading :)
Top comments (5)
Subscribe
Sapir Malka
Sapir Malka
Young fullstack developer based in Israel
-
Location
Israel
-
Work
Junior Full stack developer
-
Joined
• Jun 21 '20
- Copy link
Great article!
Sapir Malka
Sapir Malka
Young fullstack developer based in Israel
-
Location
Israel
-
Work
Junior Full stack developer
-
Joined
• Jun 21 '20
- Copy link
Really great code!
Himanshu Mishra
Himanshu Mishra
Hi, My name is Himanshu and I'm an independent maker from India. Currently working on Hoverify- tryhoverify.com
-
Location
India
-
Work
Indie Maker
-
Joined
• Jun 21 '20
- Copy link
Thanks
Bdethloff
Bdethloff
-
Joined
• May 7 '21
- Copy link
Thank you so much for this
Visakh Vijayan
Visakh Vijayan
There is nothing else in this world that gives as much happiness as coding
-
Email
vjnvisakh@gmail.com
-
Location
Kolkata, West Bengal
-
Education
MCA
-
Pronouns
he/him/his
-
Work
Full Stack Developer at JTC
-
Joined
• May 18 '21
- Copy link
nicely done. Used it in our project. Thanks
For further actions, you may consider blocking this person and/or reporting abuse