295 lines
9.4 KiB
JavaScript
295 lines
9.4 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* HexaHost.de Build Script
|
|
*
|
|
* Obfusciert JavaScript und minifiziert CSS für die Produktion
|
|
*
|
|
* Verwendung:
|
|
* npm run build - Alles bauen
|
|
* npm run build:js - Nur JavaScript
|
|
* npm run build:css - Nur CSS
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const JavaScriptObfuscator = require('javascript-obfuscator');
|
|
const CleanCSS = require('clean-css');
|
|
|
|
// Konfiguration
|
|
const config = {
|
|
srcDir: path.join(__dirname, '..'),
|
|
distDir: path.join(__dirname, '..', 'dist'),
|
|
|
|
// JavaScript-Dateien zum Obfuscieren
|
|
jsFiles: [
|
|
'assets/js/main.js',
|
|
'assets/js/contact.js',
|
|
'assets/js/cookie-consent.js'
|
|
],
|
|
|
|
// CSS-Dateien zum Minifizieren
|
|
cssFiles: [
|
|
'assets/css/style.css'
|
|
],
|
|
|
|
// PHP-Dateien (nur kopieren)
|
|
phpFiles: [
|
|
'config/config.php',
|
|
'config/mail-config.php',
|
|
'config/products-config.php',
|
|
'includes/header.php',
|
|
'includes/footer.php',
|
|
'includes/functions.php'
|
|
],
|
|
|
|
// JavaScript Obfuscator Optionen
|
|
jsObfuscatorOptions: {
|
|
compact: true,
|
|
controlFlowFlattening: true,
|
|
controlFlowFlatteningThreshold: 0.7,
|
|
deadCodeInjection: true,
|
|
deadCodeInjectionThreshold: 0.4,
|
|
debugProtection: false,
|
|
disableConsoleOutput: true,
|
|
identifierNamesGenerator: 'hexadecimal',
|
|
log: false,
|
|
numbersToExpressions: true,
|
|
renameGlobals: false,
|
|
selfDefending: true,
|
|
simplify: true,
|
|
splitStrings: true,
|
|
splitStringsChunkLength: 10,
|
|
stringArray: true,
|
|
stringArrayCallsTransform: true,
|
|
stringArrayEncoding: ['base64'],
|
|
stringArrayIndexShift: true,
|
|
stringArrayRotate: true,
|
|
stringArrayShuffle: true,
|
|
stringArrayWrappersCount: 2,
|
|
stringArrayWrappersChainedCalls: true,
|
|
stringArrayWrappersParametersMaxCount: 4,
|
|
stringArrayWrappersType: 'function',
|
|
stringArrayThreshold: 0.75,
|
|
transformObjectKeys: true,
|
|
unicodeEscapeSequence: false
|
|
},
|
|
|
|
// Clean-CSS Optionen
|
|
cssMinifyOptions: {
|
|
level: {
|
|
1: {
|
|
specialComments: 0
|
|
},
|
|
2: {
|
|
mergeMedia: true,
|
|
removeEmpty: true,
|
|
removeDuplicateFontRules: true,
|
|
removeDuplicateMediaBlocks: true,
|
|
removeDuplicateRules: true
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// Hilfsfunktionen
|
|
function ensureDir(dir) {
|
|
if (!fs.existsSync(dir)) {
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
}
|
|
}
|
|
|
|
function copyFile(src, dest) {
|
|
ensureDir(path.dirname(dest));
|
|
fs.copyFileSync(src, dest);
|
|
}
|
|
|
|
function formatBytes(bytes) {
|
|
if (bytes === 0) return '0 Bytes';
|
|
const k = 1024;
|
|
const sizes = ['Bytes', 'KB', 'MB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
}
|
|
|
|
function getCompressionRatio(original, compressed) {
|
|
return ((1 - compressed / original) * 100).toFixed(1);
|
|
}
|
|
|
|
// JavaScript obfuscieren
|
|
function obfuscateJS(filePath) {
|
|
const srcPath = path.join(config.srcDir, filePath);
|
|
const destPath = path.join(config.distDir, filePath);
|
|
|
|
if (!fs.existsSync(srcPath)) {
|
|
console.log(` ⚠️ Datei nicht gefunden: ${filePath}`);
|
|
return null;
|
|
}
|
|
|
|
const originalCode = fs.readFileSync(srcPath, 'utf8');
|
|
const originalSize = Buffer.byteLength(originalCode, 'utf8');
|
|
|
|
try {
|
|
const obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
originalCode,
|
|
config.jsObfuscatorOptions
|
|
).getObfuscatedCode();
|
|
|
|
const obfuscatedSize = Buffer.byteLength(obfuscatedCode, 'utf8');
|
|
|
|
ensureDir(path.dirname(destPath));
|
|
fs.writeFileSync(destPath, obfuscatedCode);
|
|
|
|
return {
|
|
file: filePath,
|
|
originalSize,
|
|
newSize: obfuscatedSize,
|
|
ratio: getCompressionRatio(originalSize, obfuscatedSize)
|
|
};
|
|
} catch (error) {
|
|
console.log(` ❌ Fehler bei ${filePath}: ${error.message}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// CSS minifizieren
|
|
function minifyCSS(filePath) {
|
|
const srcPath = path.join(config.srcDir, filePath);
|
|
const destPath = path.join(config.distDir, filePath);
|
|
|
|
if (!fs.existsSync(srcPath)) {
|
|
console.log(` ⚠️ Datei nicht gefunden: ${filePath}`);
|
|
return null;
|
|
}
|
|
|
|
const originalCode = fs.readFileSync(srcPath, 'utf8');
|
|
const originalSize = Buffer.byteLength(originalCode, 'utf8');
|
|
|
|
try {
|
|
const minified = new CleanCSS(config.cssMinifyOptions).minify(originalCode);
|
|
|
|
if (minified.errors.length > 0) {
|
|
console.log(` ❌ Fehler bei ${filePath}: ${minified.errors.join(', ')}`);
|
|
return null;
|
|
}
|
|
|
|
const minifiedSize = Buffer.byteLength(minified.styles, 'utf8');
|
|
|
|
ensureDir(path.dirname(destPath));
|
|
fs.writeFileSync(destPath, minified.styles);
|
|
|
|
return {
|
|
file: filePath,
|
|
originalSize,
|
|
newSize: minifiedSize,
|
|
ratio: getCompressionRatio(originalSize, minifiedSize)
|
|
};
|
|
} catch (error) {
|
|
console.log(` ❌ Fehler bei ${filePath}: ${error.message}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// PHP-Dateien kopieren (keine Obfuscation)
|
|
function copyPHP(filePath) {
|
|
const srcPath = path.join(config.srcDir, filePath);
|
|
const destPath = path.join(config.distDir, filePath);
|
|
|
|
if (!fs.existsSync(srcPath)) {
|
|
console.log(` ⚠️ Datei nicht gefunden: ${filePath}`);
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
copyFile(srcPath, destPath);
|
|
const size = fs.statSync(srcPath).size;
|
|
|
|
return {
|
|
file: filePath,
|
|
originalSize: size,
|
|
newSize: size,
|
|
ratio: '0'
|
|
};
|
|
} catch (error) {
|
|
console.log(` ❌ Fehler bei ${filePath}: ${error.message}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Hauptfunktion
|
|
function build() {
|
|
const args = process.argv.slice(2);
|
|
const jsOnly = args.includes('--js-only');
|
|
const cssOnly = args.includes('--css-only');
|
|
|
|
console.log('\n╔════════════════════════════════════════════════════════════╗');
|
|
console.log('║ HexaHost.de - Build System ║');
|
|
console.log('║ Obfuscation & Minification ║');
|
|
console.log('╚════════════════════════════════════════════════════════════╝\n');
|
|
|
|
// dist-Verzeichnis erstellen/leeren
|
|
if (fs.existsSync(config.distDir)) {
|
|
fs.rmSync(config.distDir, { recursive: true });
|
|
}
|
|
ensureDir(config.distDir);
|
|
|
|
const results = [];
|
|
|
|
// JavaScript obfuscieren
|
|
if (!cssOnly) {
|
|
console.log('📦 JavaScript obfuscieren...\n');
|
|
config.jsFiles.forEach(file => {
|
|
process.stdout.write(` → ${file}... `);
|
|
const result = obfuscateJS(file);
|
|
if (result) {
|
|
console.log(`✓ (${formatBytes(result.originalSize)} → ${formatBytes(result.newSize)}, -${result.ratio}%)`);
|
|
results.push(result);
|
|
}
|
|
});
|
|
console.log();
|
|
}
|
|
|
|
// CSS minifizieren
|
|
if (!jsOnly) {
|
|
console.log('🎨 CSS minifizieren...\n');
|
|
config.cssFiles.forEach(file => {
|
|
process.stdout.write(` → ${file}... `);
|
|
const result = minifyCSS(file);
|
|
if (result) {
|
|
console.log(`✓ (${formatBytes(result.originalSize)} → ${formatBytes(result.newSize)}, -${result.ratio}%)`);
|
|
results.push(result);
|
|
}
|
|
});
|
|
console.log();
|
|
}
|
|
|
|
// PHP-Dateien kopieren
|
|
if (!jsOnly && !cssOnly) {
|
|
console.log('📄 PHP-Dateien kopieren...\n');
|
|
config.phpFiles.forEach(file => {
|
|
process.stdout.write(` → ${file}... `);
|
|
const result = copyPHP(file);
|
|
if (result) {
|
|
console.log(`✓ (${formatBytes(result.originalSize)})`);
|
|
results.push(result);
|
|
}
|
|
});
|
|
console.log();
|
|
}
|
|
|
|
// Zusammenfassung
|
|
const totalOriginal = results.reduce((sum, r) => sum + r.originalSize, 0);
|
|
const totalNew = results.reduce((sum, r) => sum + r.newSize, 0);
|
|
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
console.log(`✅ Build abgeschlossen!`);
|
|
console.log(` Dateien: ${results.length}`);
|
|
console.log(` Original: ${formatBytes(totalOriginal)}`);
|
|
console.log(` Optimiert: ${formatBytes(totalNew)}`);
|
|
console.log(` Ersparnis: ${formatBytes(totalOriginal - totalNew)} (${getCompressionRatio(totalOriginal, totalNew)}%)`);
|
|
console.log(` Ausgabe: ${config.distDir}`);
|
|
console.log('═══════════════════════════════════════════════════════════════\n');
|
|
}
|
|
|
|
// Build starten
|
|
build();
|