faster smaller

This commit is contained in:
Andrey Kondratev
2025-11-09 18:48:57 +05:00
parent ca27a2b3f0
commit 6db48b16a7
11 changed files with 470 additions and 76 deletions

127
scripts/minify.js Executable file
View File

@@ -0,0 +1,127 @@
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const { minify } = require('terser');
const { minify: minifyHtml } = require('html-minifier-terser');
const publicDir = path.join(__dirname, '..', 'public');
const distDir = path.join(publicDir, 'dist');
async function minifyJavaScript() {
console.log('🔧 Minifying JavaScript...');
const jsFile = path.join(distDir, 'script.js');
if (!fs.existsSync(jsFile)) {
console.error('❌ script.js not found. Run build first.');
process.exit(1);
}
const code = fs.readFileSync(jsFile, 'utf8');
const result = await minify(code, {
compress: {
dead_code: true,
drop_console: false, // Keep console for debugging
drop_debugger: true,
keep_classnames: true,
keep_fnames: false,
passes: 2
},
mangle: {
keep_classnames: true,
keep_fnames: false
},
format: {
comments: false
},
sourceMap: {
filename: 'script.js',
url: 'script.js.map'
}
});
if (result.code) {
fs.writeFileSync(jsFile, result.code);
if (result.map) {
fs.writeFileSync(jsFile + '.map', result.map);
}
const originalSize = Buffer.byteLength(code, 'utf8');
const minifiedSize = Buffer.byteLength(result.code, 'utf8');
const savings = ((1 - minifiedSize / originalSize) * 100).toFixed(1);
console.log(`✅ JavaScript minified: ${originalSize}${minifiedSize} bytes (${savings}% reduction)`);
} else {
console.error('❌ Minification failed');
process.exit(1);
}
}
async function minifyHTML() {
console.log('🔧 Minifying HTML...');
const htmlFile = path.join(publicDir, 'index.html');
if (!fs.existsSync(htmlFile)) {
console.error('❌ index.html not found');
return;
}
const html = fs.readFileSync(htmlFile, 'utf8');
const minified = await minifyHtml(html, {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
minifyCSS: true,
minifyJS: false, // Don't minify inline JS (we handle it separately)
keepClosingSlash: true
});
const originalSize = Buffer.byteLength(html, 'utf8');
const minifiedSize = Buffer.byteLength(minified, 'utf8');
const savings = ((1 - minifiedSize / originalSize) * 100).toFixed(1);
// Save to dist folder
fs.writeFileSync(path.join(publicDir, 'index.min.html'), minified);
console.log(`✅ HTML minified: ${originalSize}${minifiedSize} bytes (${savings}% reduction)`);
}
async function minifyCSS() {
console.log('🔧 Checking CSS...');
const cssFile = path.join(publicDir, 'style.css');
if (!fs.existsSync(cssFile)) {
console.log(' No CSS file to minify');
return;
}
const css = fs.readFileSync(cssFile, 'utf8');
const originalSize = Buffer.byteLength(css, 'utf8');
console.log(` CSS size: ${originalSize} bytes (already optimized)`);
}
async function main() {
console.log('🚀 Starting minification process...\n');
try {
await minifyJavaScript();
await minifyHTML();
await minifyCSS();
console.log('\n✨ All files minified successfully!');
} catch (error) {
console.error('❌ Minification error:', error);
process.exit(1);
}
}
main();