/** * Build Verification Script * * Verifies that the production build was successful and contains * all necessary files for deployment. */ import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const DIST_DIR = path.join(__dirname, '..', 'dist'); const REQUIRED_FILES = [ 'index.html', 'assets' // Directory ]; const errors = []; const warnings = []; console.log('šŸ” Verifying build output...\n'); // Check if dist directory exists if (!fs.existsSync(DIST_DIR)) { errors.push('dist/ directory not found - build may have failed'); console.error('āŒ dist/ directory not found'); process.exit(1); } console.log(`šŸ“ Build directory: ${DIST_DIR}`); // Check required files console.log('\nšŸ“‹ Checking required files:'); for (const file of REQUIRED_FILES) { const filePath = path.join(DIST_DIR, file); const exists = fs.existsSync(filePath); if (exists) { const stats = fs.statSync(filePath); const isDir = stats.isDirectory(); console.log(` āœ… ${file} ${isDir ? '(directory)' : `(${(stats.size / 1024).toFixed(2)} KB)`}`); } else { errors.push(`Required file missing: ${file}`); console.log(` āŒ ${file} - MISSING`); } } // Check for JavaScript bundles console.log('\nšŸ“¦ Checking JavaScript bundles:'); const assetsDir = path.join(DIST_DIR, 'assets'); if (fs.existsSync(assetsDir)) { const files = fs.readdirSync(assetsDir); const jsFiles = files.filter(f => f.endsWith('.js')); const cssFiles = files.filter(f => f.endsWith('.css')); if (jsFiles.length === 0) { errors.push('No JavaScript bundles found in assets/'); console.log(' āŒ No JavaScript bundles found'); } else { console.log(` āœ… Found ${jsFiles.length} JavaScript bundles`); // Show bundle sizes const totalJsSize = jsFiles.reduce((total, file) => { const stats = fs.statSync(path.join(assetsDir, file)); return total + stats.size; }, 0); console.log(` Total JS size: ${(totalJsSize / 1024 / 1024).toFixed(2)} MB`); // Warn if bundles are too large jsFiles.forEach(file => { const stats = fs.statSync(path.join(assetsDir, file)); const sizeMB = stats.size / 1024 / 1024; if (sizeMB > 1) { warnings.push(`Large bundle detected: ${file} (${sizeMB.toFixed(2)} MB)`); } }); } if (cssFiles.length === 0) { warnings.push('No CSS files found in assets/'); console.log(' āš ļø No CSS files found'); } else { console.log(` āœ… Found ${cssFiles.length} CSS files`); } } else { errors.push('assets/ directory not found'); console.log(' āŒ assets/ directory not found'); } // Check index.html console.log('\nšŸ“„ Checking index.html:'); const indexPath = path.join(DIST_DIR, 'index.html'); if (fs.existsSync(indexPath)) { const content = fs.readFileSync(indexPath, 'utf8'); // Check for script tags const scriptTags = content.match(/]*src="[^"]*"[^>]*>/g); if (scriptTags && scriptTags.length > 0) { console.log(` āœ… Found ${scriptTags.length} script tag(s)`); } else { errors.push('No script tags found in index.html'); console.log(' āŒ No script tags found'); } // Check for stylesheet links const linkTags = content.match(/]*rel="stylesheet"[^>]*>/g); if (linkTags && linkTags.length > 0) { console.log(` āœ… Found ${linkTags.length} stylesheet link(s)`); } else { warnings.push('No stylesheet links found in index.html'); console.log(' āš ļø No stylesheet links found'); } } else { errors.push('index.html not found'); console.log(' āŒ index.html not found'); } // Calculate total build size console.log('\nšŸ“Š Build Statistics:'); function getDirSize(dirPath) { let size = 0; const files = fs.readdirSync(dirPath); for (const file of files) { const filePath = path.join(dirPath, file); const stats = fs.statSync(filePath); if (stats.isDirectory()) { size += getDirSize(filePath); } else { size += stats.size; } } return size; } const totalSize = getDirSize(DIST_DIR); console.log(` Total build size: ${(totalSize / 1024 / 1024).toFixed(2)} MB`); // Summary console.log('\n' + '='.repeat(50)); if (errors.length > 0) { console.log('\nāŒ Build verification FAILED\n'); errors.forEach(error => console.error(` - ${error}`)); process.exit(1); } if (warnings.length > 0) { console.log('\nāš ļø Build verification passed with warnings:\n'); warnings.forEach(warning => console.warn(` - ${warning}`)); } console.log('\nāœ… Build verification PASSED'); console.log(' All required files present and valid'); console.log(' Ready for deployment\n');