This document explains the validation systems in place to prevent build configuration issues and catch problems early.
The Meteo app uses a multi-layered validation system to ensure build configurations remain consistent across development, Docker, and CI/CD environments:
- Package Configuration Validator - Validates package.json, Dockerfiles, and source code
- Docker Build Verifier - Tests actual Docker builds and container startup
- Pre-build Hooks - Automatic validation before every build
- CI/CD Integration - Validation in GitHub Actions pipeline
frontend/scripts/validate-build-config.cjs
Manual validation:
cd frontend
npm run validateAutomatic validation (runs before every build):
npm run build # Runs validation automatically via prebuild hook- ✅ Required scripts exist:
dev,build,preview,test,lint - ❌ Deprecated scripts removed:
start,eject(CRA legacy) - ✅ Scripts use correct commands (
vite, notreact-scripts)
- ✅ Development Dockerfile uses
npm run dev - ✅ Production Dockerfile uses
npm run build - ❌ No deprecated
npm startcommands
- ✅ All env vars use
VITE_prefix (notREACT_APP_) - ✅ Consistent naming across .env files
- ✅ Docker build args match Vite naming
- ✅ No
process.env.REACT_APP_*references - ✅ Uses
import.meta.env.VITE_*instead - ✅ No CommonJS
require()in main source (ESM only) - ✅ Dynamic imports use ESM syntax
- ✅ Valid vite.config.js exists
- ✅ Required plugins configured (React)
- ✅ Build output directory set correctly
- ✅ GitHub Actions uses correct npm commands
- ✅ Workflow validates before building
- ✅ Environment variables match Vite naming
- ✅ Uses
/paths (not%PUBLIC_URL%) - ✅ Script tag has
type="module" - ✅ Proper Vite entry point
╔════════════════════════════════════════════════╗
║ Build Configuration Validator ║
╚════════════════════════════════════════════════╝
✓ package.json has all required scripts
✓ No deprecated CRA scripts found
⚠ WARNING: Found 'validate' script using .cjs extension
✅ All checks passed! (1 warnings)
Exit codes:
0- All checks passed (warnings allowed)1- Critical errors found (build will fail)
Error: Missing required script
✗ ERROR: package.json missing required script: dev
Fix: Add the script to package.json:
{
"scripts": {
"dev": "vite"
}
}Error: Deprecated script found
✗ ERROR: package.json contains deprecated CRA script: start
Fix: Remove or rename the script:
{
"scripts": {
"start": "vite" // Should be "dev": "vite"
}
}Error: Environment variable naming
✗ ERROR: Found REACT_APP_API_URL in src/config/api.js
Fix: Update to Vite naming:
// Before
const API_URL = process.env.REACT_APP_API_URL;
// After
const API_URL = import.meta.env.VITE_API_URL;scripts/verify-docker-build.sh
# From project root
./scripts/verify-docker-build.sh
# Or with bash
bash scripts/verify-docker-build.sh- ✅
frontend/Dockerfile.devexists - ✅
frontend/Dockerfile.prodexists - ✅
backend/Dockerfileexists
- ❌ No
npm startin Dockerfiles - ✅ Uses
npm run devornpm run build
- Builds all Docker images to catch build-time errors
- Tests with actual build arguments
- Validates multi-stage builds complete
- Starts development container
- Waits 5 seconds for initialization
- Verifies container is still running (didn't crash)
- Shows logs if container fails
- Verifies
index.htmlexists in build output - Checks JavaScript assets were generated
- Validates Nginx serving directory structure
╔════════════════════════════════════════════════╗
║ Docker Build Verification ║
╚════════════════════════════════════════════════╝
ℹ Checking Dockerfiles...
✓ frontend/Dockerfile.dev exists
✓ frontend/Dockerfile.prod exists
✓ backend/Dockerfile exists
ℹ Building frontend development Docker image...
✓ Frontend dev image built successfully
ℹ Testing frontend dev container...
✓ Frontend dev container started successfully
╔════════════════════════════════════════════════╗
║ Verification Summary ║
╚════════════════════════════════════════════════╝
✅ All Docker builds verified successfully!
Exit codes:
0- All validations passed1- One or more checks failed
Error: Container exited immediately
ℹ Container logs:
Error: Cannot find module '/app/src/index.js'
✗ ERROR: Frontend dev container exited immediately
Fix: Check Dockerfile CMD uses correct script:
# Wrong
CMD ["npm", "start"]
# Correct
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "3000"]Error: Image failed to build
✗ ERROR: Frontend prod image failed to build
Fix:
- Check Docker build logs:
docker build -f frontend/Dockerfile.prod frontend - Verify build arguments are passed:
--build-arg VITE_API_URL=... - Check package.json has correct build script
The prebuild script in package.json runs automatically before build:
{
"scripts": {
"prebuild": "npm run validate",
"build": "vite build"
}
}When you run:
npm run buildThis happens automatically:
npm run prebuildexecutes first- Validation script runs all checks
- If validation passes → build continues
- If validation fails → build is aborted (exit code 1)
Not recommended, but if needed:
# Skip prebuild hook
npm run build --ignore-scripts
# Or run vite directly
npx vite buildThe validation runs in the CI/CD pipeline at .github/workflows/ci.yml:
- name: Validate build configuration
run: |
cd frontend
npm run validate- ✅ Every push to
mainbranch - ✅ Every pull request to
mainbranch - ✅ Before running tests
- ✅ Before building the application
- Checkout code
- Install dependencies
- → Validate configuration (new step)
- Run linter
- Run tests
- Build application
- Build Docker images
If validation fails in CI/CD:
- ❌ Build is marked as failed
- ❌ Pull request cannot be merged (if branch protection enabled)
- 📧 Team receives notification
- 🔍 Check logs show which validation failed
Example failure output:
Run cd frontend
cd frontend
npm run validate
> validate
> node scripts/validate-build-config.cjs
✗ ERROR: Dockerfile.dev contains deprecated 'npm start'
✗ ERROR: Found REACT_APP_API_URL in 2 files
❌ Validation failed! Found 2 errors.
Error: Process completed with exit code 1.
-
Run validation locally before pushing:
npm run validate
-
Test Docker builds locally:
./scripts/verify-docker-build.sh
-
Check validation in pre-commit:
- Husky pre-commit hooks run linting automatically
- Consider adding validation to pre-push hook
-
Update validation when adding new features:
- New environment variables? Update validator
- New Docker stages? Update Docker verifier
- New npm scripts? Update required scripts list
-
Keep validation fast:
- Validation should complete in < 5 seconds
- Docker verification runs separately (slower)
-
Run validation early:
- Before installing all dependencies (when possible)
- Before expensive operations like testing
-
Clear error messages:
- Validator provides specific file locations
- Suggests fixes for common issues
-
Required checks before deploy:
# 1. Validate configuration npm run validate # 2. Run tests npm test # 3. Verify Docker builds ./scripts/verify-docker-build.sh # 4. Build for production npm run build
-
Environment-specific validation:
- Development: Relaxed warnings
- Staging: Strict validation
- Production: Zero tolerance for errors
Error: Cannot find module 'validate-build-config.cjs'
Fix: Ensure script exists at frontend/scripts/validate-build-config.cjs
Error: Permission denied: ./scripts/verify-docker-build.sh
Fix: Make script executable:
chmod +x scripts/verify-docker-build.shIf validator reports errors incorrectly:
-
Check if issue is in comments:
- Validator may flag commented-out code
- Consider removing outdated comments
-
Check third-party dependencies:
- Some libraries may use patterns that trigger warnings
- Add exceptions to validator if needed
-
Report false positives:
- Open issue with validation output
- Include specific file and line number
If validation passes but builds still fail:
-
Update validator to catch the issue:
- Add new validation check for the failure case
- Submit PR with improved validation
-
Check for race conditions:
- File changed between validation and build
- Use git commit hooks to validate at commit time
-
Check for environment-specific issues:
- Different Node.js versions
- Missing environment variables
- OS-specific path issues
To add a new validation check to validate-build-config.cjs:
function validateMyNewCheck() {
console.log('\n' + colors.blue + 'Checking my new feature...' + colors.reset);
// Your validation logic
if (somethingIsWrong) {
error('Description of the problem');
return;
}
success('My new check passed');
}
// Add to main validation flow
validatePackageJson();
validateDockerfiles();
validateMyNewCheck(); // Add hereCreate team-specific validators:
# Custom validator for backend
backend/scripts/validate-backend.js
# Custom validator for infrastructure
scripts/validate-infrastructure.shAdd to package.json:
{
"scripts": {
"validate": "npm run validate:frontend && npm run validate:backend",
"validate:frontend": "node frontend/scripts/validate-build-config.cjs",
"validate:backend": "node backend/scripts/validate-backend.js"
}
}The validation system provides multiple layers of protection:
| Layer | Speed | When | Purpose |
|---|---|---|---|
| Package Validator | Fast (< 5s) | Pre-build, CI/CD | Config consistency |
| Docker Verifier | Slow (1-2min) | Manual, pre-deploy | Container functionality |
| Pre-build Hook | Fast (< 5s) | Every build | Automatic safety |
| CI/CD Check | Fast (< 5s) | Push/PR | Team protection |
Key benefits:
- 🚀 Catches issues before deployment
- 🛡️ Prevents configuration drift
- ⚡ Fails fast with clear error messages
- 📚 Enforces best practices automatically
- 🔄 Works across development, Docker, and CI/CD
- Vite Migration Guide - Understanding the Vite setup
- Development Guide - Setting up local environment
- Docker Documentation - Docker build and deployment
- CI/CD Documentation - GitHub Actions setup