feat: Build-System für Obfuscation und Minification hinzugefügt

- package.json mit Build-Dependencies
- Build-Script für JavaScript Obfuscation (javascript-obfuscator)
- CSS Minification (clean-css)
- Automatisches Kopieren der PHP-Dateien
This commit is contained in:
TheOnlyMace
2026-01-16 19:50:47 +01:00
parent 465bc84b2a
commit 1d2cc945a3
4 changed files with 2028 additions and 0 deletions

23
.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
# Dependencies
node_modules/
# Build Output (nur in main branch)
# dist/
# Logs
*.log
npm-debug.log*
# OS
.DS_Store
Thumbs.db
# IDE
.idea/
.vscode/
*.swp
*.swo
# Temporäre Dateien
*.tmp
*.temp

1686
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
package.json Normal file
View File

@@ -0,0 +1,26 @@
{
"name": "hexahost-backend",
"version": "1.0.0",
"description": "HexaHost.de Backend - Build-System für Obfuscation und Minification",
"scripts": {
"build": "node scripts/build.js",
"build:js": "node scripts/build.js --js-only",
"build:css": "node scripts/build.js --css-only",
"clean": "rm -rf dist",
"watch": "node scripts/watch.js"
},
"devDependencies": {
"javascript-obfuscator": "^4.1.1",
"clean-css": "^5.3.3",
"chokidar": "^3.6.0",
"chalk": "^4.1.2"
},
"keywords": [
"hexahost",
"obfuscation",
"minification",
"build"
],
"author": "HexaHost.de",
"license": "LGPL-2.1"
}

293
scripts/build.js Normal file
View File

@@ -0,0 +1,293 @@
#!/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',
'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();