feat(website): add build-time minification and optimize meta descriptions

This commit is contained in:
Koala
2026-06-01 02:10:27 +02:00
parent 1bb2123da2
commit 14be38fe11
15 changed files with 787 additions and 3305 deletions
+93 -2
View File
@@ -6,6 +6,82 @@
const fs = require('fs');
const path = require('path');
// Minify CSS: strips comments, collapses whitespace, removes trailing semicolons
function minifyCSS(code) {
return code
.replace(/\/\*[\s\S]*?\*\//g, '')
.replace(/\s*([{}:;,])\s*/g, '$1')
.replace(/\s+/g, ' ')
.replace(/;\}/g, '}')
.trim();
}
// Minify JS: state-machine that tracks string context so
// // inside URLs (https://) inside strings is never mistaken for a comment.
function minifyJS(code) {
var out = '';
var inSingle = false, inDouble = false, inTemplate = false;
var templateBrace = 0;
var i = 0;
while (i < code.length) {
var ch = code[i];
var next = code[i + 1] || '';
// --- Escape handling (must come before string toggle) ---
if (ch === '\\' && (inSingle || inDouble || inTemplate)) {
out += ch + next;
i += 2;
continue;
}
// --- String toggle ---
if (!inDouble && !inTemplate && ch === "'") { inSingle = !inSingle; out += ch; i++; continue; }
if (!inSingle && !inTemplate && ch === '"') { inDouble = !inDouble; out += ch; i++; continue; }
if (!inSingle && !inDouble) {
if (ch === '`' && !inTemplate) { inTemplate = true; templateBrace = 0; out += ch; i++; continue; }
if (inTemplate && ch === '`' && templateBrace === 0) { inTemplate = false; out += ch; i++; continue; }
}
// --- Template interpolation depth tracking ---
if (inTemplate && !inSingle && !inDouble) {
if (ch === '$' && next === '{') { templateBrace++; out += ch + next; i += 2; continue; }
if (ch === '}' && templateBrace > 0) { templateBrace--; out += ch; i++; continue; }
}
// --- Inside a string / template literal → output as-is ---
if (inSingle || inDouble || inTemplate) { out += ch; i++; continue; }
// --- Outside strings: handle comments ---
if (ch === '/' && next === '/') {
while (i < code.length && code[i] !== '\n') i++;
out += '\n';
i++;
continue;
}
if (ch === '/' && next === '*') {
i += 2;
while (i < code.length - 1) {
if (code[i] === '*' && code[i + 1] === '/') { i += 2; break; }
if (code[i] === '\n') out += '\n';
i++;
}
continue;
}
out += ch;
i++;
}
// Collapse horizontal whitespace (preserve newlines)
return out
.replace(/[^\S\n]+/g, ' ')
.replace(/^ +/gm, '')
.replace(/ +$/gm, '')
.replace(/\n{3,}/g, '\n\n')
.trim();
}
// Helper to recursively copy directories
function copyDirSync(src, dest) {
fs.mkdirSync(dest, { recursive: true });
@@ -18,6 +94,7 @@ function copyDirSync(src, dest) {
if (entry.isDirectory()) {
copyDirSync(srcPath, destPath);
} else {
// Binary assets (images, etc.) are copied as-is
fs.copyFileSync(srcPath, destPath);
}
}
@@ -105,8 +182,22 @@ function compile() {
const srcPath = path.join(websiteDir, file);
const destPath = path.join(wwwDir, file);
if (fs.existsSync(srcPath)) {
fs.copyFileSync(srcPath, destPath);
console.log(`Copied: ${file}`);
if (file.endsWith('.css')) {
const raw = fs.readFileSync(srcPath, 'utf8');
const minified = minifyCSS(raw);
fs.writeFileSync(destPath, minified, 'utf8');
const saved = ((raw.length - minified.length) / raw.length * 100).toFixed(0);
console.log(`Minified: ${file} (-${saved}%)`);
} else if (file.endsWith('.js')) {
const raw = fs.readFileSync(srcPath, 'utf8');
const minified = minifyJS(raw);
fs.writeFileSync(destPath, minified, 'utf8');
const saved = ((raw.length - minified.length) / raw.length * 100).toFixed(0);
console.log(`Minified: ${file} (-${saved}%)`);
} else {
fs.copyFileSync(srcPath, destPath);
console.log(`Copied: ${file}`);
}
} else {
console.warn(`Warning: Static file ${file} not found.`);
}