Architecture
Builders

Builders

The builder system is responsible for creating configuration files and managing dependencies for React applications. Builders ensure consistent, working project setups based on user choices and selected features.

๐Ÿ—๏ธ Builder Architecture


๐Ÿ“ Builder Components

โš™๏ธ Configuration Builder

Generates framework and feature configuration files

configuration-builder.js

๐Ÿ“ฆ Package JSON Builder

Builds package.json with scripts and dependencies

package-json-builder.js

๐Ÿ”— Dependency Resolver

Manages dependency placement and versions

dependency-resolver.js

๐Ÿ“š Dependencies Catalog

Version catalog and dependency definitions

dependencies.js

โš™๏ธ Configuration Builder

The Configuration Builder generates all necessary configuration files for the project.

Core Responsibilities

Framework Configuration

Creates framework-specific configuration files:

// Vite configuration
await configBuilder.generateViteConfig(projectPath, userChoices)
// Creates: vite.config.js/ts
 
// Next.js configuration  
await configBuilder.generateNextConfig(projectPath, userChoices)
// Creates: next.config.js

TypeScript Configuration

Generates TypeScript configuration when enabled:

await configBuilder.generateTypeScriptConfig(projectPath, userChoices)
// Creates: tsconfig.json with framework-specific settings

Testing Configuration

Sets up testing framework configuration:

// Vitest configuration
await configBuilder.generateVitestConfig(projectPath, userChoices)
// Creates: vitest.config.js/ts
 
// Jest configuration
await configBuilder.generateJestConfig(projectPath, userChoices)  
// Creates: jest.config.js + babel.config.json (if needed)

Styling Configuration

Creates styling-related configuration files:

// Tailwind CSS
await configBuilder.generateTailwindConfig(projectPath, userChoices)
// Creates: tailwind.config.js + postcss.config.js
 
// PostCSS (for various styling solutions)
await configBuilder.generatePostCSSConfig(projectPath, userChoices)

Configuration Templates

// Generated vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
 
export default defineConfig({
  plugins: [react()],
  server: {
    port: 5173,
    open: true
  },
  build: {
    outDir: 'dist',
    sourcemap: true
  }
})

๐Ÿ“ฆ Package JSON Builder

The Package JSON Builder creates the package.json file with appropriate scripts, dependencies, and metadata.

Core Functions

Framework-Specific Scripts:

getFrameworkScripts(framework) {
  switch (framework) {
    case 'vite':
      return {
        dev: 'vite',
        build: 'vite build',
        preview: 'vite preview'
      }
    case 'nextjs':
      return {
        dev: 'next dev',
        build: 'next build',
        start: 'next start'
      }
  }
}

Additional Scripts:

// Testing scripts (if enabled)
test: 'vitest' || 'jest'
'test:coverage': 'vitest --coverage' || 'jest --coverage'
 
// Linting scripts
lint: 'eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0'
'lint:fix': 'eslint . --ext ts,tsx --fix'
 
// Formatting scripts  
format: 'prettier --write .'
'format:check': 'prettier --check .'

๐Ÿ”— Dependency Resolver

The Dependency Resolver manages which packages go where and ensures compatibility.

Dependency Placement Logic

Framework Dependencies

Determines where framework dependencies should be placed:

getFrameworkDependencies(framework) {
  if (framework === 'vite') {
    return {
      devDependencies: {
        'vite': '^4.4.0',
        '@vitejs/plugin-react': '^4.0.0'
      }
    }
  }
  
  if (framework === 'nextjs') {
    return {
      dependencies: {
        'next': '^14.0.0'
      }
    }
  }
}

Feature Dependencies

Resolves dependencies for selected features:

getFeatureDependencies(features) {
  const deps = { dependencies: {}, devDependencies: {} }
  
  if (features.includes('typescript')) {
    deps.devDependencies = {
      ...deps.devDependencies,
      'typescript': '^5.0.0',
      '@types/react': '^18.2.0',
      '@types/react-dom': '^18.2.0'
    }
  }
  
  if (features.includes('tailwind')) {
    deps.devDependencies = {
      ...deps.devDependencies,
      'tailwindcss': '^3.3.0',
      'postcss': '^8.4.0',
      'autoprefixer': '^10.4.0'
    }
  }
  
  return deps
}

Dependency Conflicts

Resolves conflicts and ensures compatibility:

resolveDependencyConflicts(allDependencies) {
  // Handle React version conflicts
  const reactVersion = getOptimalReactVersion(allDependencies)
  
  // Ensure peer dependency compatibility
  validatePeerDependencies(allDependencies)
  
  // Remove duplicate dependencies
  return deduplicateDependencies(allDependencies)
}

Smart Dependency Management

Framework-Specific Logic: Some frameworks (like Next.js) place TypeScript in dependencies instead of devDependencies for deployment compatibility.

// Example: Next.js TypeScript handling
if (framework === 'nextjs' && features.includes('typescript')) {
  // Next.js needs TypeScript in dependencies for Vercel deployment
  dependencies['typescript'] = versions.typescript
} else if (features.includes('typescript')) {
  // Other frameworks can use devDependencies
  devDependencies['typescript'] = versions.typescript
}

๐Ÿ“š Dependencies Catalog

The dependencies catalog maintains version information and compatibility matrices.

Version Management

export const frameworks = {
  vite: {
    'vite': '^4.4.0',
    '@vitejs/plugin-react': '^4.0.0'
  },
  nextjs: {
    'next': '^14.0.0'
  }
}

Version Update Strategy

Automated Updates

Regular dependency updates through automated processes:

// Update strategy
const updateStrategy = {
  major: 'manual',      // Major updates require manual review
  minor: 'automated',   // Minor updates can be automated
  patch: 'automated'    // Patch updates are safe to automate
}

Compatibility Testing

All version updates are validated through the QA system:

# Test new dependency versions
node qa-automation/test-matrix-generator.js
node qa-automation/test-runner.js critical --full

Security Updates

Security updates are prioritized and fast-tracked:

// Security update process
if (isSecurityUpdate(dependency)) {
  prioritize(dependency)
  runSecurityTests(dependency)
  autoApprove(dependency)
}

๐Ÿ”„ Builder Workflow

The builders work together in a coordinated workflow:

Error Handling

โš ๏ธ

Validation: All builders include comprehensive validation to ensure generated configurations are valid and compatible.

// Configuration validation
validateConfiguration(config) {
  if (!config.plugins || !Array.isArray(config.plugins)) {
    throw new Error('Invalid configuration: plugins must be an array')
  }
  
  // Validate framework-specific requirements
  validateFrameworkConfig(config, framework)
  
  // Check for conflicting options
  checkForConflicts(config)
}

๐Ÿงช Testing Builders

Builders are thoroughly tested to ensure reliability:

Unit Tests

// Example builder test
describe('ConfigurationBuilder', () => {
  it('should generate valid Vite config', async () => {
    const config = await configBuilder.generateViteConfig(projectPath, {
      framework: 'vite',
      typescript: true,
      styling: 'tailwind'
    })
    
    expect(config).toContain('@vitejs/plugin-react')
    expect(config).toContain('typescript')
  })
})

Integration Tests

// Test builder coordination
describe('Builder Integration', () => {
  it('should create consistent project configuration', async () => {
    const userChoices = { framework: 'vite', typescript: true }
    
    await configBuilder.generateAll(projectPath, userChoices)
    await packageBuilder.build(projectPath, userChoices)
    
    // Verify all files are created and compatible
    expect(fs.existsSync('vite.config.ts')).toBe(true)
    expect(fs.existsSync('tsconfig.json')).toBe(true)
    expect(fs.existsSync('package.json')).toBe(true)
  })
})

๐Ÿ”ง Extending Builders

Adding New Framework Support

Update Dependencies Catalog

Add framework dependencies to dependencies.js:

export const frameworks = {
  // ... existing frameworks
  'your-framework': {
    'your-framework': '^1.0.0',
    'your-framework-plugin-react': '^1.0.0'
  }
}

Extend Configuration Builder

Add configuration generation logic:

async generateYourFrameworkConfig(projectPath, userChoices) {
  const config = {
    // Your framework-specific configuration
  }
  
  const configPath = path.join(projectPath, 'your-framework.config.js')
  await writeFile(configPath, generateConfigContent(config))
}

Update Package JSON Builder

Add framework-specific scripts:

getFrameworkScripts(framework) {
  switch (framework) {
    // ... existing cases
    case 'your-framework':
      return {
        dev: 'your-framework dev',
        build: 'your-framework build',
        start: 'your-framework start'
      }
  }
}

๐Ÿ“š Next Steps

Explore Related Systems:

Extend React Kickstart:

Consistent Configuration: The builder system ensures every generated project has consistent, working configurations that follow best practices.