Files
portal-api/scripts/minify-js.js
2025-07-24 16:18:27 +07:00

140 lines
4.3 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const JavaScriptObfuscator = require('javascript-obfuscator');
// Configuration
const config = {
compact: true,
controlFlowFlattening: false,
controlFlowFlatteningThreshold: 0.75,
deadCodeInjection: false,
deadCodeInjectionThreshold: 0.4,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: false, // Keep console.log for debugging
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
selfDefending: false,
simplify: true,
splitStrings: false,
splitStringsChunkLength: 10,
stringArray: true,
stringArrayEncoding: [],
stringArrayThreshold: 0.75,
transformObjectKeys: false,
unicodeEscapeSequence: false
};
// Directories to process
const directories = [
'resources/js',
'resources/js/service'
];
// File extensions to minify
const extensions = ['.js'];
// Files to skip (already minified or external libraries)
const skipFiles = [
'app.js', // Already processed by Laravel Mix
'app.js.LICENSE.txt',
'*.min.js', // Already minified
'sweetalert.min.js', // External minified library
'owl.carousel.js' // External library
];
function shouldSkipFile(filename) {
return skipFiles.some(pattern => {
if (pattern.includes('*')) {
const regex = new RegExp(pattern.replace('*', '.*'));
return regex.test(filename);
}
return filename === pattern;
});
}
async function minifyFile(filePath) {
try {
const source = fs.readFileSync(filePath, 'utf8');
const result = JavaScriptObfuscator.obfuscate(source, config);
if (result.error) {
console.error(`❌ Error obfuscating ${filePath}:`, result.error);
return false;
}
// Create minified file path in public/js directory
const relativePath = path.relative('resources/js', filePath);
const dir = path.dirname(relativePath);
const ext = path.extname(filePath);
const basename = path.basename(filePath, ext);
// Create output directory structure in public/js
const outputPath = path.join('public/js', dir);
if (!fs.existsSync(outputPath)) {
fs.mkdirSync(outputPath, { recursive: true });
}
const minifiedPath = path.join(outputPath, `${basename}.min${ext}`);
// Write minified file
fs.writeFileSync(minifiedPath, result.getObfuscatedCode());
// Calculate size reduction
const originalSize = fs.statSync(filePath).size;
const minifiedSize = fs.statSync(minifiedPath).size;
const reduction = ((originalSize - minifiedSize) / originalSize * 100).toFixed(1);
console.log(`✅ ${filePath} → ${minifiedPath} (${reduction}% smaller, obfuscated)`);
return true;
} catch (error) {
console.error(`❌ Failed to obfuscate ${filePath}:`, error.message);
return false;
}
}
function processDirectory(dirPath) {
if (!fs.existsSync(dirPath)) {
console.log(`⚠️ Directory not found: ${dirPath}`);
return;
}
const files = fs.readdirSync(dirPath);
files.forEach(file => {
const filePath = path.join(dirPath, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
processDirectory(filePath);
} else if (stat.isFile()) {
const ext = path.extname(file);
if (extensions.includes(ext) && !shouldSkipFile(file)) {
minifyFile(filePath);
}
}
});
}
async function main() {
console.log('🚀 Starting JavaScript obfuscation and minification...\n');
let totalFiles = 0;
let successFiles = 0;
for (const dir of directories) {
console.log(`📁 Processing directory: ${dir}`);
processDirectory(dir);
}
console.log('\n✨ Obfuscation and minification complete!');
console.log('\n📝 To use obfuscated files, update your Blade templates:');
console.log(' - Replace .js with .min.js');
console.log(' - Example: <script src="{{ asset("js/whois.min.js") }}"></script>');
console.log('\n🔒 Files are now obfuscated for better security!');
}
// Run the script
main().catch(console.error);