Move to tailwind-build instead of CDNs
This commit is contained in:
Executable
+112
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const https = require('https');
|
||||
|
||||
const buildDir = {
|
||||
css: './pkg/web/assets/build/css',
|
||||
js: './pkg/web/assets/build/js',
|
||||
fonts: './pkg/web/assets/build/fonts'
|
||||
};
|
||||
|
||||
// Create directories
|
||||
Object.values(buildDir).forEach(dir => {
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
// Download function
|
||||
function downloadFile(url, filepath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log(`📥 Downloading ${path.basename(filepath)}...`);
|
||||
|
||||
const file = fs.createWriteStream(filepath);
|
||||
|
||||
https.get(url, (response) => {
|
||||
if (response.statusCode === 200) {
|
||||
response.pipe(file);
|
||||
file.on('finish', () => {
|
||||
file.close();
|
||||
const stats = fs.statSync(filepath);
|
||||
const size = (stats.size / 1024).toFixed(1) + 'KB';
|
||||
console.log(` ✓ Downloaded ${path.basename(filepath)} (${size})`);
|
||||
resolve();
|
||||
});
|
||||
} else if (response.statusCode === 302 || response.statusCode === 301) {
|
||||
downloadFile(response.headers.location, filepath).then(resolve).catch(reject);
|
||||
} else {
|
||||
reject(new Error(`Failed to download ${url}: ${response.statusCode}`));
|
||||
}
|
||||
}).on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
// Download text content
|
||||
function downloadText(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
https.get(url, (response) => {
|
||||
let data = '';
|
||||
response.on('data', chunk => data += chunk);
|
||||
response.on('end', () => {
|
||||
if (response.statusCode === 200) {
|
||||
resolve(data);
|
||||
} else {
|
||||
reject(new Error(`Failed to download ${url}: ${response.statusCode}`));
|
||||
}
|
||||
});
|
||||
}).on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
// Files to download
|
||||
const downloads = [
|
||||
{
|
||||
url: 'https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/fonts/bootstrap-icons.woff',
|
||||
path: path.join(buildDir.fonts, 'bootstrap-icons.woff')
|
||||
},
|
||||
{
|
||||
url: 'https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/fonts/bootstrap-icons.woff2',
|
||||
path: path.join(buildDir.fonts, 'bootstrap-icons.woff2')
|
||||
},
|
||||
{
|
||||
url: 'https://code.jquery.com/jquery-3.7.1.min.js',
|
||||
path: path.join(buildDir.js, 'jquery-3.7.1.min.js')
|
||||
}
|
||||
];
|
||||
|
||||
// Download all files
|
||||
async function downloadAssets() {
|
||||
console.log('📦 Downloading external assets...\n');
|
||||
|
||||
try {
|
||||
// Download Bootstrap Icons CSS and fix paths
|
||||
console.log('📥 Downloading Bootstrap Icons CSS...');
|
||||
const biCSS = await downloadText('https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.css');
|
||||
|
||||
// Fix font paths to point to our local fonts
|
||||
const fixedCSS = biCSS.replace(
|
||||
/url\("\.\/fonts\//g,
|
||||
'url("../fonts/'
|
||||
);
|
||||
|
||||
// Write fixed CSS to source directory so it can be minified
|
||||
const biCSSSourcePath = path.join('./pkg/web/assets/css', 'bootstrap-icons.css');
|
||||
fs.writeFileSync(biCSSSourcePath, fixedCSS);
|
||||
console.log(` ✓ Downloaded Bootstrap Icons CSS (${(fixedCSS.length/1024).toFixed(1)}KB)`);
|
||||
|
||||
// Download other assets
|
||||
for (const download of downloads) {
|
||||
await downloadFile(download.url, download.path);
|
||||
}
|
||||
|
||||
console.log('\n✅ External assets downloaded successfully!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('💥 Error downloading assets:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
downloadAssets();
|
||||
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const CleanCSS = require('clean-css');
|
||||
|
||||
const sourceDir = './pkg/web/assets/css';
|
||||
const buildDir = './pkg/web/assets/build/css';
|
||||
|
||||
// Create build directory
|
||||
if (!fs.existsSync(buildDir)) {
|
||||
fs.mkdirSync(buildDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Create source directory if it doesn't exist
|
||||
if (!fs.existsSync(sourceDir)) {
|
||||
fs.mkdirSync(sourceDir, { recursive: true });
|
||||
}
|
||||
|
||||
const cleanCSS = new CleanCSS({
|
||||
level: 2, // Aggressive optimization
|
||||
returnPromise: false
|
||||
});
|
||||
|
||||
function minifyFile(inputPath, outputPath) {
|
||||
try {
|
||||
console.log(`🎨 Minifying ${path.basename(inputPath)}...`);
|
||||
|
||||
const css = fs.readFileSync(inputPath, 'utf8');
|
||||
const result = cleanCSS.minify(css);
|
||||
|
||||
if (result.errors.length > 0) {
|
||||
throw new Error(result.errors.join('\n'));
|
||||
}
|
||||
|
||||
fs.writeFileSync(outputPath, result.styles);
|
||||
|
||||
// Show size reduction
|
||||
const originalSize = Buffer.byteLength(css, 'utf8');
|
||||
const minifiedSize = Buffer.byteLength(result.styles, 'utf8');
|
||||
const reduction = ((originalSize - minifiedSize) / originalSize * 100).toFixed(1);
|
||||
|
||||
console.log(` ✓ ${path.basename(inputPath)}: ${(originalSize/1024).toFixed(1)}KB → ${(minifiedSize/1024).toFixed(1)}KB (${reduction}% reduction)`);
|
||||
|
||||
return { original: originalSize, minified: minifiedSize };
|
||||
|
||||
} catch (error) {
|
||||
console.error(` ✗ Error minifying ${inputPath}:`, error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function minifyAllCSS() {
|
||||
console.log('🎨 Minifying additional CSS files...\n');
|
||||
|
||||
try {
|
||||
// Get all CSS files from source directory (excluding the main styles.css which is built by Tailwind)
|
||||
const cssFiles = fs.readdirSync(sourceDir).filter(file =>
|
||||
file.endsWith('.css') && file !== 'styles.css'
|
||||
);
|
||||
|
||||
if (cssFiles.length === 0) {
|
||||
console.log('ℹ️ No additional CSS files found to minify');
|
||||
return;
|
||||
}
|
||||
|
||||
let totalOriginal = 0;
|
||||
let totalMinified = 0;
|
||||
let processedFiles = 0;
|
||||
|
||||
// Minify each file
|
||||
cssFiles.forEach(file => {
|
||||
const inputPath = path.join(sourceDir, file);
|
||||
const outputPath = path.join(buildDir, file);
|
||||
const result = minifyFile(inputPath, outputPath);
|
||||
|
||||
if (result) {
|
||||
totalOriginal += result.original;
|
||||
totalMinified += result.minified;
|
||||
processedFiles++;
|
||||
}
|
||||
});
|
||||
|
||||
if (processedFiles > 0) {
|
||||
const totalReduction = ((totalOriginal - totalMinified) / totalOriginal * 100).toFixed(1);
|
||||
console.log(`\n✅ Successfully minified ${processedFiles}/${cssFiles.length} additional CSS file(s)`);
|
||||
console.log(`📊 Total: ${(totalOriginal/1024).toFixed(1)}KB → ${(totalMinified/1024).toFixed(1)}KB (${totalReduction}% reduction)`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('💥 Error during CSS minification:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
minifyAllCSS();
|
||||
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { minify } = require('terser');
|
||||
|
||||
const sourceDir = './pkg/web/assets/js';
|
||||
const buildDir = './pkg/web/assets/build/js';
|
||||
|
||||
// Create build directory
|
||||
if (!fs.existsSync(buildDir)) {
|
||||
fs.mkdirSync(buildDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Minify options
|
||||
const minifyOptions = {
|
||||
compress: {
|
||||
drop_console: false, // Keep console.log for debugging
|
||||
drop_debugger: true,
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
booleans: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
},
|
||||
mangle: {
|
||||
toplevel: false,
|
||||
reserved: [
|
||||
'$', 'jQuery', 'decypharrUtils', 'configManager', 'repairManager',
|
||||
'RepairManager', 'RepairUtils', 'ConfigManager', 'window', 'document'
|
||||
]
|
||||
},
|
||||
format: {
|
||||
comments: false,
|
||||
beautify: false
|
||||
}
|
||||
};
|
||||
|
||||
async function minifyFile(inputPath, outputPath) {
|
||||
try {
|
||||
console.log(`🗜️ Minifying ${path.basename(inputPath)}...`);
|
||||
|
||||
const code = fs.readFileSync(inputPath, 'utf8');
|
||||
const result = await minify(code, minifyOptions);
|
||||
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
|
||||
fs.writeFileSync(outputPath, result.code);
|
||||
|
||||
// Show size reduction
|
||||
const originalSize = fs.statSync(inputPath).size;
|
||||
const minifiedSize = fs.statSync(outputPath).size;
|
||||
const reduction = ((originalSize - minifiedSize) / originalSize * 100).toFixed(1);
|
||||
|
||||
console.log(` ✓ ${path.basename(inputPath)}: ${(originalSize/1024).toFixed(1)}KB → ${(minifiedSize/1024).toFixed(1)}KB (${reduction}% reduction)`);
|
||||
|
||||
return { original: originalSize, minified: minifiedSize };
|
||||
|
||||
} catch (error) {
|
||||
console.error(` ✗ Error minifying ${inputPath}:`, error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function minifyAllJS() {
|
||||
console.log('📦 Minifying JavaScript files...\n');
|
||||
|
||||
try {
|
||||
// Check if source directory exists
|
||||
if (!fs.existsSync(sourceDir)) {
|
||||
console.log(`Creating source directory ${sourceDir}...`);
|
||||
fs.mkdirSync(sourceDir, { recursive: true });
|
||||
console.log('ℹ️ No JavaScript files found to minify');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all JS files from source directory
|
||||
const jsFiles = fs.readdirSync(sourceDir).filter(file => file.endsWith('.js'));
|
||||
|
||||
if (jsFiles.length === 0) {
|
||||
console.log('ℹ️ No JavaScript files found to minify');
|
||||
return;
|
||||
}
|
||||
|
||||
let totalOriginal = 0;
|
||||
let totalMinified = 0;
|
||||
let processedFiles = 0;
|
||||
|
||||
// Minify each file
|
||||
for (const file of jsFiles) {
|
||||
const inputPath = path.join(sourceDir, file);
|
||||
const outputPath = path.join(buildDir, file);
|
||||
const result = await minifyFile(inputPath, outputPath);
|
||||
|
||||
if (result) {
|
||||
totalOriginal += result.original;
|
||||
totalMinified += result.minified;
|
||||
processedFiles++;
|
||||
}
|
||||
}
|
||||
|
||||
if (processedFiles > 0) {
|
||||
const totalReduction = ((totalOriginal - totalMinified) / totalOriginal * 100).toFixed(1);
|
||||
console.log(`\n✅ Successfully minified ${processedFiles}/${jsFiles.length} JavaScript file(s)`);
|
||||
console.log(`📊 Total: ${(totalOriginal/1024).toFixed(1)}KB → ${(totalMinified/1024).toFixed(1)}KB (${totalReduction}% reduction)`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('💥 Error during JavaScript minification:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
minifyAllJS();
|
||||
Reference in New Issue
Block a user