Skip to content

Latest commit

 

History

History
425 lines (325 loc) · 11.9 KB

File metadata and controls

425 lines (325 loc) · 11.9 KB

Vite Migration Guide

This document describes the migration from Create React App (CRA) to Vite for the Meteo Weather App frontend.

Overview

Date: November 4, 2025 Migrated From: Create React App (react-scripts 5.0.1) Migrated To: Vite 6.0.7 Added: TypeScript support (gradual), ESLint, Prettier, Husky pre-commit hooks

Why Migrate to Vite?

  1. 10-100x faster builds - Vite uses native ESM and esbuild
  2. Instant HMR (Hot Module Replacement) - No full page reloads
  3. Active maintenance - CRA is deprecated and in maintenance mode
  4. Better DX - Faster development experience
  5. Smaller bundles - Better tree-shaking and code splitting

Changes Made

1. Configuration Files

New Files Created:

  • vite.config.js - Vite configuration with dev server, build settings, and Vitest
  • tsconfig.json - TypeScript configuration (allows gradual migration)
  • tsconfig.node.json - TypeScript config for build tools
  • .eslintrc.json - ESLint configuration for code quality
  • .prettierrc - Prettier configuration for code formatting
  • .prettierignore - Files to exclude from formatting
  • .husky/pre-commit - Git pre-commit hook for linting/formatting
  • .env.example - Example environment variables

Files Moved:

  • public/index.htmlindex.html (Vite requires index.html at root)

Files Modified:

  • package.json - Updated scripts, dependencies, and configuration
  • .env - Changed REACT_APP_* to VITE_* prefix

2. Environment Variables

Before (CRA):

REACT_APP_API_URL=http://localhost:5001/api
REACT_APP_OPENWEATHER_API_KEY=your_key_here

After (Vite):

VITE_API_URL=http://localhost:5001/api
VITE_OPENWEATHER_API_KEY=your_key_here

In Code:

// Before (CRA)
const apiKey = process.env.REACT_APP_OPENWEATHER_API_KEY;

// After (Vite)
const apiKey = import.meta.env.VITE_OPENWEATHER_API_KEY;

3. Package.json Changes

Dependencies Removed:

  • react-scripts - No longer needed

Dependencies Moved to devDependencies:

  • @testing-library/* packages
  • All testing utilities

New devDependencies Added:

  • vite - Build tool
  • @vitejs/plugin-react - React plugin for Vite
  • vitest - Test runner (Vite-native, replaces Jest)
  • @vitest/coverage-v8 - Coverage reporting
  • typescript - TypeScript support
  • @types/react, @types/react-dom - React type definitions
  • eslint and plugins - Linting
  • prettier - Code formatting
  • husky - Git hooks
  • lint-staged - Run linters on staged files
  • jsdom - DOM environment for tests

New Scripts:

{
  "dev": "vite",                    // Start dev server (replaces 'start')
  "build": "vite build",            // Build for production
  "preview": "vite preview",        // Preview production build
  "test": "vitest",                 // Run tests in watch mode
  "test:ui": "vitest --ui",         // Run tests with UI
  "test:coverage": "vitest run --coverage",
  "test:ci": "vitest run --coverage",
  "lint": "eslint . --ext js,jsx",
  "lint:fix": "eslint . --ext js,jsx --fix",
  "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"",
  "format:check": "prettier --check \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"",
  "type-check": "tsc --noEmit"
}

4. Source Code Changes

Files Modified:

  1. src/config/api.js - Changed process.env.REACT_APP_API_URL to import.meta.env.VITE_API_URL
  2. src/components/weather/RadarMap.jsx:
    • Changed process.env.REACT_APP_OPENWEATHER_API_KEY to import.meta.env.VITE_OPENWEATHER_API_KEY
    • Replaced require() with ESM imports for Leaflet marker images
  3. src/components/settings/UserPreferencesPage.jsx - Updated env var reference

CommonJS to ESM:

// Before (CRA - CommonJS)
const markerIcon = require('leaflet/dist/images/marker-icon.png');

// After (Vite - ESM)
import markerIcon from 'leaflet/dist/images/marker-icon.png';

5. Docker Configuration

frontend/Dockerfile.prod Changes:

  • Updated Node.js version: node:18-alpinenode:24-alpine
  • Changed build args: REACT_APP_*VITE_*
  • Changed npm install: npm install --omit=devnpm ci (needs devDependencies for build)
  • Updated comments to reference Vite

docker-compose.prod.yml Changes:

  • Build args: REACT_APP_API_URLVITE_API_URL
  • Build args: REACT_APP_OPENWEATHER_API_KEYVITE_OPENWEATHER_API_KEY

6. CI/CD Changes

.github/workflows/ci.yml Changes:

  • Test command: npm test -- --coverage ...npm run test:ci
  • Lint command: Now always runs (no fallback)
  • Build env vars: REACT_APP_API_URLVITE_API_URL

7. Test Configuration

Before (Jest via CRA):

  • Configuration in package.json under "jest"

After (Vitest):

  • Configuration in vite.config.js under test
  • Same coverage thresholds maintained (25/15/20/25)
  • Same exclude patterns
  • Compatible API with Jest (minimal test changes needed)

Migration Steps (For Reference)

If you need to migrate another project:

  1. Install Vite and dependencies:

    cd frontend
    npm install --save-dev vite @vitejs/plugin-react vitest @vitest/coverage-v8 jsdom
    npm uninstall react-scripts
  2. Create configuration files:

    • vite.config.js
    • tsconfig.json
    • .eslintrc.json
    • .prettierrc
  3. Move index.html to root:

    mv public/index.html .
  4. Update index.html:

    • Remove %PUBLIC_URL% (replace with /)
    • Add <script type="module" src="/src/index.js"></script> before </body>
  5. Update environment variables:

    • Rename .env variables from REACT_APP_* to VITE_*
    • Update all code references from process.env.REACT_APP_* to import.meta.env.VITE_*
  6. Replace CommonJS with ESM:

    • Find all require() statements
    • Replace with import statements
  7. Update package.json scripts:

    • Replace CRA scripts with Vite scripts
  8. Update Docker and CI/CD:

    • Update Dockerfile build args
    • Update docker-compose environment variables
    • Update GitHub Actions workflows
  9. Test everything:

    npm run dev        # Test dev server
    npm run build      # Test production build
    npm run preview    # Test production build locally
    npm test           # Test suite
    npm run lint       # Linting

New Features Available

1. TypeScript Support (Gradual Migration)

You can now start using TypeScript:

// MyComponent.tsx
import React from 'react';

interface Props {
  title: string;
  count: number;
}

const MyComponent: React.FC<Props> = ({ title, count }) => {
  return <h1>{title}: {count}</h1>;
};

export default MyComponent;
  • No need to migrate all at once - .js and .jsx files work alongside .ts and .tsx
  • Run npm run type-check to check for type errors
  • TypeScript strict mode is OFF to allow gradual adoption

2. Path Aliases

Configured in vite.config.js and tsconfig.json:

// Before
import MyComponent from '../../../components/MyComponent';

// After
import MyComponent from '@components/MyComponent';
import utils from '@utils/helpers';

Available aliases:

  • @/*src/*
  • @components/*src/components/*
  • @contexts/*src/contexts/*
  • @utils/*src/utils/*

3. Pre-commit Hooks

Husky automatically runs linting and formatting before each commit:

git add .
git commit -m "Your message"
# → Automatically runs ESLint and Prettier on staged files
# → Commit only succeeds if linting passes

To bypass (use sparingly):

git commit -m "Your message" --no-verify

4. Better Code Splitting

Vite automatically splits vendors:

  • react-vendor.js - React, React DOM, React Router
  • chart-vendor.js - Recharts
  • map-vendor.js - Leaflet, React Leaflet

This improves caching and initial load time.

Performance Improvements

Development Server:

  • CRA: ~30-60 seconds cold start
  • Vite: ~1-3 seconds cold start ⚡

Hot Module Replacement (HMR):

  • CRA: 2-5 seconds (full reload)
  • Vite: <100ms (instant) ⚡

Production Build:

  • CRA: ~60-120 seconds
  • Vite: ~15-30 seconds ⚡

Bundle Size:

  • CRA: Potentially larger bundles
  • Vite: Better tree-shaking, ~10-20% smaller ⚡

Commands Reference

Development:

npm run dev              # Start dev server (http://localhost:3000)
npm run preview          # Preview production build locally

Build:

npm run build            # Build for production (outputs to 'build/')

Testing:

npm test                 # Run tests in watch mode
npm run test:ui          # Run tests with UI
npm run test:coverage    # Run tests with coverage
npm run test:ci          # Run tests once (for CI/CD)

Code Quality:

npm run lint             # Check for linting errors
npm run lint:fix         # Auto-fix linting errors
npm run format           # Format code with Prettier
npm run format:check     # Check if code is formatted
npm run type-check       # Check TypeScript types (no emit)

Troubleshooting

Issue: "require is not defined"

Solution: Replace require() with ESM import

Issue: Environment variables not working

Solution: Ensure variables start with VITE_ and use import.meta.env.VITE_*

Issue: Tests failing

Solution: Vitest is Jest-compatible but may need minor adjustments. Check Vitest docs.

Issue: Build fails in Docker

Solution: Ensure npm ci is used (not npm install --omit=dev) to include devDependencies

Issue: Pre-commit hooks not running

Solution: Run npm run prepare to initialize Husky

Rollback Plan

If you need to rollback to CRA (not recommended):

  1. Restore package.json from git history
  2. Delete Vite config files
  3. Move index.html back to public/
  4. Restore original index.html content
  5. Change env vars back to REACT_APP_* prefix
  6. Run npm install

Next Steps

Immediate:

  • ✅ Test all functionality works with Vite
  • ✅ Verify production builds work
  • ✅ Update deployment scripts if needed

Short-term (1-2 weeks):

  • Gradually convert components to TypeScript (start with new features)
  • Increase ESLint strictness
  • Add more comprehensive linting rules
  • Increase test coverage

Long-term (1-3 months):

  • Migrate entire codebase to TypeScript
  • Add E2E tests with Playwright or Cypress
  • Consider Vite PWA plugin for better PWA support
  • Explore Vite's SSR capabilities for future features

Build Validation System

To prevent configuration drift and catch issues early, we've implemented a comprehensive validation system:

Package Configuration Validator

cd frontend
npm run validate

This validates:

  • package.json scripts consistency
  • Dockerfile commands match npm scripts
  • Environment variable naming (VITE_ prefix)
  • Source code patterns (ESM, env vars)
  • Vite configuration completeness
  • CI/CD workflow alignment

Docker Build Verifier

./scripts/verify-docker-build.sh

This tests:

  • Dockerfile existence and syntax
  • Actual Docker image builds
  • Container startup functionality
  • Production build output structure

Pre-build Hook

Validation runs automatically before every build:

npm run build  # Runs validation first

For complete documentation: See docs/BUILD_VALIDATION.md

Resources

Support

For issues or questions:

  1. Check Vite Discord
  2. Search Vite GitHub Issues
  3. Check Vitest Documentation
  4. Review Build Validation Guide for build errors

Migration completed by: Claude (Anthropic AI) Date: November 4, 2025 Status: ✅ Complete - Ready for testing