128 lines
3.7 KiB
JavaScript
Executable File
128 lines
3.7 KiB
JavaScript
Executable File
#!/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();
|