123 lines
4.0 KiB
JavaScript
123 lines
4.0 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Script pour analyser les bundles JavaScript et calculer les économies
|
|
* Lance après npm run build
|
|
*/
|
|
|
|
import { readFileSync, readdirSync, statSync } from 'fs';
|
|
import { join } from 'path';
|
|
|
|
const DIST_DIR = './dist/assets/js';
|
|
const COLORS = {
|
|
reset: '\x1b[0m',
|
|
bright: '\x1b[1m',
|
|
green: '\x1b[32m',
|
|
yellow: '\x1b[33m',
|
|
blue: '\x1b[36m',
|
|
red: '\x1b[31m',
|
|
};
|
|
|
|
function formatSize(bytes) {
|
|
const kb = bytes / 1024;
|
|
return kb.toFixed(2) + ' KiB';
|
|
}
|
|
|
|
function analyzeBundle() {
|
|
console.log(`\n${COLORS.bright}${COLORS.blue}📊 Analyse du Bundle JavaScript${COLORS.reset}\n`);
|
|
console.log('━'.repeat(80));
|
|
|
|
try {
|
|
const files = readdirSync(DIST_DIR);
|
|
const jsFiles = files.filter(f => f.endsWith('.js'));
|
|
|
|
let totalSize = 0;
|
|
const chunks = [];
|
|
|
|
jsFiles.forEach(file => {
|
|
const filePath = join(DIST_DIR, file);
|
|
const stats = statSync(filePath);
|
|
totalSize += stats.size;
|
|
|
|
// Extraire le nom du chunk
|
|
const chunkName = file.split('-')[0];
|
|
|
|
chunks.push({
|
|
name: file,
|
|
chunkName,
|
|
size: stats.size,
|
|
});
|
|
});
|
|
|
|
// Trier par taille décroissante
|
|
chunks.sort((a, b) => b.size - a.size);
|
|
|
|
// Afficher les chunks
|
|
console.log(`${COLORS.bright}Fichiers JavaScript générés :${COLORS.reset}\n`);
|
|
|
|
chunks.forEach((chunk, index) => {
|
|
const bar = '█'.repeat(Math.ceil(chunk.size / (totalSize / 50)));
|
|
const percentage = ((chunk.size / totalSize) * 100).toFixed(1);
|
|
|
|
let color = COLORS.green;
|
|
if (chunk.size > 100 * 1024) color = COLORS.red;
|
|
else if (chunk.size > 50 * 1024) color = COLORS.yellow;
|
|
|
|
console.log(
|
|
`${index + 1}. ${COLORS.bright}${chunk.name}${COLORS.reset}`
|
|
);
|
|
console.log(
|
|
` ${color}${bar}${COLORS.reset} ${formatSize(chunk.size)} (${percentage}%)`
|
|
);
|
|
console.log();
|
|
});
|
|
|
|
console.log('━'.repeat(80));
|
|
console.log(
|
|
`${COLORS.bright}Total JavaScript:${COLORS.reset} ${COLORS.green}${formatSize(totalSize)}${COLORS.reset}`
|
|
);
|
|
|
|
// Calculer les économies estimées
|
|
const beforeOptimization = 231 * 1024; // 231 KiB avant
|
|
const savings = beforeOptimization - totalSize;
|
|
const savingsPercent = ((savings / beforeOptimization) * 100).toFixed(1);
|
|
|
|
if (savings > 0) {
|
|
console.log(
|
|
`${COLORS.bright}Économies:${COLORS.reset} ${COLORS.green}${formatSize(savings)} (-${savingsPercent}%)${COLORS.reset}`
|
|
);
|
|
}
|
|
|
|
console.log('━'.repeat(80));
|
|
|
|
// Recommandations
|
|
console.log(`\n${COLORS.bright}${COLORS.blue}💡 Recommandations${COLORS.reset}\n`);
|
|
|
|
const largeChunks = chunks.filter(c => c.size > 100 * 1024);
|
|
if (largeChunks.length > 0) {
|
|
console.log(`${COLORS.yellow}⚠️ Chunks volumineux détectés (> 100 KiB):${COLORS.reset}`);
|
|
largeChunks.forEach(chunk => {
|
|
console.log(` - ${chunk.name}: ${formatSize(chunk.size)}`);
|
|
});
|
|
console.log(` ${COLORS.bright}→ Considérez le lazy loading ou le code splitting${COLORS.reset}\n`);
|
|
} else {
|
|
console.log(`${COLORS.green}✓ Tous les chunks sont optimisés${COLORS.reset}\n`);
|
|
}
|
|
|
|
// Vérifications de performance
|
|
console.log(`${COLORS.bright}Performance Checklist:${COLORS.reset}`);
|
|
console.log(`${totalSize < 150 * 1024 ? COLORS.green + '✓' : COLORS.red + '✗'} Bundle total < 150 KiB ${COLORS.reset}`);
|
|
console.log(`${chunks[0].size < 100 * 1024 ? COLORS.green + '✓' : COLORS.red + '✗'} Plus gros chunk < 100 KiB ${COLORS.reset}`);
|
|
console.log(`${chunks.length > 3 ? COLORS.green + '✓' : COLORS.yellow + '⚠'} Code splitting activé (${chunks.length} chunks) ${COLORS.reset}`);
|
|
|
|
console.log();
|
|
|
|
} catch (error) {
|
|
console.error(`${COLORS.red}Erreur lors de l'analyse:${COLORS.reset}`, error.message);
|
|
console.log(`\n${COLORS.yellow}💡 Assurez-vous d'avoir lancé 'npm run build' d'abord${COLORS.reset}\n`);
|
|
}
|
|
}
|
|
|
|
// Lancer l'analyse
|
|
analyzeBundle();
|