169 lines
5.2 KiB
JavaScript
169 lines
5.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Script d'optimisation du bundle pour Veza V5 Ultra
|
|
* Objectif: Bundle < 150KB initial, chunks < 50KB
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { execSync } = require('child_process');
|
|
|
|
console.log('🚀 VEZA V5 ULTRA - Bundle Optimization');
|
|
console.log('=====================================\n');
|
|
|
|
// Configuration Vite pour l'optimisation
|
|
const viteConfig = `
|
|
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { resolve } from 'path';
|
|
|
|
export default defineConfig({
|
|
plugins: [react()],
|
|
resolve: {
|
|
alias: {
|
|
'@': resolve(__dirname, './src'),
|
|
},
|
|
},
|
|
build: {
|
|
target: 'esnext',
|
|
minify: 'terser',
|
|
terserOptions: {
|
|
compress: {
|
|
drop_console: true,
|
|
drop_debugger: true,
|
|
pure_funcs: ['console.log', 'console.info'],
|
|
passes: 2,
|
|
},
|
|
mangle: {
|
|
safari10: true,
|
|
},
|
|
},
|
|
rollupOptions: {
|
|
output: {
|
|
manualChunks: {
|
|
// Vendor chunks
|
|
'react-vendor': ['react', 'react-dom'],
|
|
'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu', '@radix-ui/react-tabs'],
|
|
'audio-vendor': ['three', '@react-three/fiber'],
|
|
'utils-vendor': ['framer-motion', '@tanstack/react-virtual', 'zustand'],
|
|
|
|
// Feature chunks
|
|
'audio-engine': ['./src/services/audio-engine-v5.ts'],
|
|
'visualizer': ['./src/components/audio/AudioVisualizer3D.tsx'],
|
|
'virtual-list': ['./src/components/ui/virtual-list.tsx'],
|
|
'command-palette': ['./src/components/ui/command-palette.tsx'],
|
|
},
|
|
chunkFileNames: (chunkInfo) => {
|
|
const facadeModuleId = chunkInfo.facadeModuleId ? chunkInfo.facadeModuleId.split('/').pop() : 'chunk';
|
|
return \`js/\${facadeModuleId}.[hash].js\`;
|
|
},
|
|
entryFileNames: 'js/[name].[hash].js',
|
|
assetFileNames: (assetInfo) => {
|
|
const info = assetInfo.name.split('.');
|
|
const ext = info[info.length - 1];
|
|
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(ext)) {
|
|
return \`img/[name].[hash].\${ext}\`;
|
|
}
|
|
if (/woff2?|eot|ttf|otf/i.test(ext)) {
|
|
return \`fonts/[name].[hash].\${ext}\`;
|
|
}
|
|
return \`assets/[name].[hash].\${ext}\`;
|
|
},
|
|
},
|
|
},
|
|
chunkSizeWarningLimit: 50,
|
|
sourcemap: false,
|
|
reportCompressedSize: true,
|
|
},
|
|
esbuild: {
|
|
drop: ['console', 'debugger'],
|
|
},
|
|
});
|
|
`;
|
|
|
|
// Écrire la config Vite optimisée
|
|
fs.writeFileSync('vite.config.optimized.js', viteConfig);
|
|
|
|
console.log('✅ Configuration Vite optimisée créée');
|
|
|
|
// Scripts package.json pour l'optimisation
|
|
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
|
|
packageJson.scripts = {
|
|
...packageJson.scripts,
|
|
'build:optimized': 'vite build --config vite.config.optimized.js',
|
|
'analyze:bundle': 'npx vite-bundle-analyzer dist',
|
|
'prod:prepare': 'rm -rf dist node_modules/.vite && npm ci',
|
|
'prod:build': 'npm run build:optimized',
|
|
'prod:test': 'npm run test:unit && npm run test:e2e',
|
|
'prod:analyze': 'npm run analyze:bundle',
|
|
'prod:deploy': 'echo "Deploy to production"',
|
|
'prod:smoke': 'echo "Run smoke tests"',
|
|
'prod:monitor': 'echo "Start monitoring"',
|
|
};
|
|
|
|
fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2));
|
|
|
|
console.log('✅ Scripts de production ajoutés');
|
|
|
|
// Analyse du bundle actuel
|
|
console.log('\n📊 Analyse du bundle actuel...');
|
|
|
|
try {
|
|
execSync('npm run build', { stdio: 'inherit' });
|
|
|
|
// Analyser la taille du bundle
|
|
const distPath = path.join(__dirname, 'dist');
|
|
if (fs.existsSync(distPath)) {
|
|
const files = fs.readdirSync(distPath, { recursive: true });
|
|
let totalSize = 0;
|
|
let jsFiles = [];
|
|
|
|
files.forEach(file => {
|
|
const filePath = path.join(distPath, file);
|
|
if (fs.statSync(filePath).isFile()) {
|
|
const size = fs.statSync(filePath).size;
|
|
totalSize += size;
|
|
|
|
if (file.endsWith('.js')) {
|
|
jsFiles.push({ name: file, size });
|
|
}
|
|
}
|
|
});
|
|
|
|
console.log('\n📈 Statistiques du bundle:');
|
|
console.log(`Total size: ${(totalSize / 1024).toFixed(2)} KB`);
|
|
console.log(`JS files: ${jsFiles.length}`);
|
|
|
|
jsFiles
|
|
.sort((a, b) => b.size - a.size)
|
|
.slice(0, 10)
|
|
.forEach(file => {
|
|
console.log(` ${file.name}: ${(file.size / 1024).toFixed(2)} KB`);
|
|
});
|
|
|
|
const initialBundle = jsFiles.find(f => f.name.includes('index'))?.size || 0;
|
|
console.log(`\nInitial bundle: ${(initialBundle / 1024).toFixed(2)} KB`);
|
|
|
|
if (initialBundle > 150 * 1024) {
|
|
console.log('⚠️ Bundle trop gros! Objectif: < 150KB');
|
|
} else {
|
|
console.log('✅ Bundle dans les objectifs!');
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('❌ Erreur lors du build:', error.message);
|
|
}
|
|
|
|
console.log('\n🎯 Optimisations appliquées:');
|
|
console.log('- Code splitting agressif');
|
|
console.log('- Tree shaking maximal');
|
|
console.log('- Compression Terser');
|
|
console.log('- Chunks manuels par feature');
|
|
console.log('- Suppression console.log');
|
|
console.log('- Minification avancée');
|
|
|
|
console.log('\n🚀 Pour optimiser:');
|
|
console.log('npm run build:optimized');
|
|
console.log('npm run analyze:bundle');
|