You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

20 KiB

Build Pattern Conversion Plan

Author: Matthew Raymer Date: 2025-07-09 Status: PLANNING - Ready for Implementation

Overview

Convert TimeSafari's build instruction pattern from the current script-based approach to a new Vite mode-based pattern that provides better environment management and consistency across all build targets.

Why Vite Mode Instead of NODE_ENV?

Vite's Native Mode System

Vite is designed to work with mode, which:

  • Determines the .env file to load (e.g. .env.production, .env.test, etc.)
  • Is passed to defineConfig(({ mode }) => {...}) in vite.config.ts
  • Is used to set behavior for dev/prod/test at config level
  • Provides better integration with Vite's build system

NODE_ENV Limitations

NODE_ENV is legacy from Webpack-era tooling:

  • You can't change NODE_ENV manually and expect Vite to adapt
  • Vite does not map NODE_ENV back to mode
  • It's redundant with mode and might conflict with assumptions
  • Limited integration with Vite's environment loading system

Usage Pattern

# Correct: Use Vite's mode system
vite build --mode production
vite build --mode development
vite build --mode test

# Only if third-party libraries require NODE_ENV
NODE_ENV=production vite build --mode production

Development vs Build Environments

Development Environment:

  • Build with defaults: npm run build:* - Uses --mode development by default
  • Purpose: Development builds for testing and debugging
  • Output: Bundled files with development optimizations

Testing/Production Environments:

  • Build with explicit mode: npm run build:* -- --mode test/production
  • Purpose: Validate and deploy the bundled application
  • Output: Optimized, bundled files for specific environment

Mode Override Behavior

How --mode Override Works:

# Base script (no hardcoded mode)
"build:electron": "vite build --config vite.config.electron.mts"

# Development (uses Vite's default: --mode development)
npm run build:electron
# Executes: vite build --config vite.config.electron.mts

# Testing (explicitly overrides with --mode test)
npm run build:electron -- --mode test
# Executes: vite build --config vite.config.electron.mts --mode test

# Production (explicitly overrides with --mode production)
npm run build:electron -- --mode production
# Executes: vite build --config vite.config.electron.mts --mode production

Key Points:

  • Base scripts have no hardcoded --mode to allow override
  • npm run build:electron defaults to --mode development
  • npm run build:electron -- --mode test overrides to --mode test
  • Vite uses the last --mode argument if multiple are provided

Capacitor Platform-Specific Commands

Capacitor requires platform-specific sync commands after building:

# General sync (copies web assets to all platforms)
npm run build:capacitor && npx cap sync

# Platform-specific sync
npm run build:capacitor && npx cap sync android
npm run build:capacitor && npx cap sync ios

# Environment-specific with platform sync
npm run build:capacitor -- --mode production && npx cap sync android
npm run build:capacitor -- --mode development && npx cap sync ios

Docker Build Commands

Docker builds include both Vite asset generation and Docker image creation:

# General Docker build (Vite build + Docker image)
npm run build:web:docker

# Environment-specific Docker builds
npm run build:web:docker:test  # Test environment + Docker image
npm run build:web:docker:prod  # Production environment + Docker image

# Manual mode overrides for Docker builds
npm run build:web:docker -- --mode test
npm run build:web:docker -- --mode production

Docker Build Process:

  1. Vite Build: Creates optimized web assets with environment-specific variables
  2. Docker Build: Creates Docker image using Dockerfile in project root
  3. Image Tagging: Images are tagged as timesafari-web for consistent management

Key Features:

  • Complete end-to-end Docker workflow in single command
  • Environment-aware builds (test/production configurations)
  • Consistent image tagging for deployment
  • Mode override flexibility for custom environments

Electron Platform-Specific Commands

Electron requires platform-specific build commands after the Vite build:

# General Electron build (Vite build only)
npm run build:electron

# Platform-specific builds
npm run build:electron:windows  # Windows executable
npm run build:electron:mac      # macOS app bundle
npm run build:electron:linux    # Linux executable

# Package-specific builds
npm run build:electron:appimage # Linux AppImage
npm run build:electron:dmg      # macOS DMG installer

# Environment-specific builds
npm run build:electron -- --mode development
npm run build:electron -- --mode test
npm run build:electron -- --mode production

# Environment-specific with platform builds
npm run build:electron:windows -- --mode development
npm run build:electron:windows -- --mode test
npm run build:electron:windows -- --mode production

npm run build:electron:mac -- --mode development
npm run build:electron:mac -- --mode test
npm run build:electron:mac -- --mode production

npm run build:electron:linux -- --mode development
npm run build:electron:linux -- --mode test
npm run build:electron:linux -- --mode production

# Environment-specific with package builds
npm run build:electron:appimage -- --mode development
npm run build:electron:appimage -- --mode test
npm run build:electron:appimage -- --mode production

npm run build:electron:dmg -- --mode development
npm run build:electron:dmg -- --mode test
npm run build:electron:dmg -- --mode production

Current State Analysis

Existing Build Scripts

  • Web: build:web - Uses vite.config.web.mts
  • Capacitor: build:capacitor - Uses vite.config.capacitor.mts
    • Android: build:android - Shell script wrapper
    • iOS: build:ios - Shell script wrapper
  • Electron: build:electron - Uses vite.config.electron.mts
    • Windows: build:electron:windows - Windows executable
    • macOS: build:electron:mac - macOS app bundle
    • Linux: build:electron:linux - Linux executable
    • AppImage: build:electron:appimage - Linux AppImage
    • DMG: build:electron:dmg - macOS DMG installer

Current package.json Scripts

{
  "build:capacitor": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --mode capacitor --config vite.config.capacitor.mts",
  "build:web": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --config vite.config.web.mts",
  "build:electron": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --mode electron --config vite.config.electron.mts"
}

Target Pattern

New Vite Mode-Based Pattern

# Development builds (defaults to --mode development)
npm run build:web-dev
npm run build:capacitor-dev
npm run build:electron-dev

# Testing builds (bundle required)
npm run build:web -- --mode test
npm run build:capacitor -- --mode test && npx cap sync
npm run build:electron -- --mode test

# Production builds (bundle required)
npm run build:web -- --mode production
npm run build:capacitor -- --mode production && npx cap sync
npm run build:electron -- --mode production

# Docker builds
npm run build:web:docker -- --mode test
npm run build:web:docker -- --mode production

# Docker environment-specific builds
npm run build:web:docker:test
npm run build:web:docker:prod

# Capacitor platform-specific builds
npm run build:capacitor:android -- --mode test
npm run build:capacitor:android -- --mode production

npm run build:capacitor:ios -- --mode test
npm run build:capacitor:ios -- --mode production

# Electron platform-specific builds
npm run build:electron:windows -- --mode test
npm run build:electron:windows -- --mode production

npm run build:electron:mac -- --mode test
npm run build:electron:mac -- --mode production

npm run build:electron:linux -- --mode test
npm run build:electron:linux -- --mode production

# Electron package-specific builds
npm run build:electron:appimage -- --mode test
npm run build:electron:appimage -- --mode production

npm run build:electron:dmg -- --mode test
npm run build:electron:dmg -- --mode production

New package.json Scripts Structure

{
  "build:web": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite --mode development --config vite.config.web.mts",
  "build:web:dev": "npm run build:web",
  "build:web:build": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --mode development --config vite.config.web.mts",
  "build:web:test": "npm run build:web:build -- --mode test",
  "build:web:prod": "npm run build:web:build -- --mode production",
  "build:web:docker": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --config vite.config.web.mts && docker build -t timesafari-web .",
  "build:web:docker:test": "npm run build:web:docker -- --mode test",
  "build:web:docker:prod": "npm run build:web:docker -- --mode production",

  "build:capacitor": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --mode capacitor --config vite.config.capacitor.mts",
  "build:capacitor-dev": "npm run build:capacitor",
  "build:capacitor:sync": "npm run build:capacitor && npx cap sync",
  "build:capacitor:android": "npm run build:capacitor:sync && npx cap sync android",
  "build:capacitor:ios": "npm run build:capacitor:sync && npx cap sync ios",

  "build:electron": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --config vite.config.electron.mts",
  "build:electron:dev": "npm run build:electron && cd electron && npm run electron:start",
  "build:electron:windows": "npm run build:electron && cd electron && npm run build:windows",
  "build:electron:mac": "npm run build:electron && cd electron && npm run build:mac",
  "build:electron:linux": "npm run build:electron && cd electron && npm run build:linux",
  "build:electron:appimage": "npm run build:electron:linux && cd electron && npm run build:appimage",
  "build:electron:dmg": "npm run build:electron:mac && cd electron && npm run build:dmg"
}

Implementation Plan

Phase 1: Environment Configuration (Day 1)

1.1 Update Vite Configurations

  • vite.config.web.mts: Add mode-based configuration
  • vite.config.capacitor.mts: Add mode-based configuration
  • vite.config.electron.mts: Add mode-based configuration
  • vite.config.common.mts: Add environment-specific variables

1.2 Environment Variables Setup

  • Create .env.development file for development settings
  • Create .env.test file for testing settings
  • Create .env.production file for production settings
  • Update .env.example with new pattern

1.3 Environment Detection Logic

// vite.config.common.mts
export default defineConfig(({ mode }) => {
  const getEnvironmentConfig = (mode: string) => {
    switch (mode) {
      case 'production':
        return { /* production settings */ };
      case 'test':
        return { /* testing settings */ };
      default:
        return { /* development settings */ };
    }
  };

  return {
    define: {
      __DEV__: mode === 'development',
      __TEST__: mode === 'test',
      __PROD__: mode === 'production'
    },
    // ... other config
  };
});

Phase 2: Package.json Scripts Update (Day 1)

2.1 Web Build Scripts

{
  "build:web": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --config vite.config.web.mts",
  "build:web-dev": "npm run build:web",
  "build:web-test": "npm run build:web -- --mode test",
  "build:web-prod": "npm run build:web -- --mode production"
}

2.2 Capacitor Build Scripts

{
  "build:capacitor": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --mode capacitor --config vite.config.capacitor.mts",
  "build:capacitor-dev": "npm run build:capacitor",
  "build:capacitor:sync": "npm run build:capacitor && npx cap sync",
  "build:capacitor:android": "npm run build:capacitor:sync && npx cap sync android",
  "build:capacitor:ios": "npm run build:capacitor:sync && npx cap sync ios",
  "build:capacitor-test": "npm run build:capacitor -- --mode test && npx cap sync",
  "build:capacitor-prod": "npm run build:capacitor -- --mode production && npx cap sync",
  "build:capacitor:android-test": "npm run build:capacitor -- --mode test && npx cap sync android",
  "build:capacitor:android-prod": "npm run build:capacitor -- --mode production && npx cap sync android",
  "build:capacitor:ios-test": "npm run build:capacitor -- --mode test && npx cap sync ios",
  "build:capacitor:ios-prod": "npm run build:capacitor -- --mode production && npx cap sync ios"
}

2.3 Electron Build Scripts

{
  "build:electron": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --config vite.config.electron.mts",
  "build:electron-dev": "npm run build:electron",
  "build:electron:windows": "npm run build:electron && cd electron && npm run build:windows",
  "build:electron:mac": "npm run build:electron && cd electron && npm run build:mac",
  "build:electron:linux": "npm run build:electron && cd electron && npm run build:linux",
  "build:electron:appimage": "npm run build:electron:linux && cd electron && npm run build:appimage",
  "build:electron:dmg": "npm run build:electron:mac && cd electron && npm run build:dmg",
  "build:electron-test": "npm run build:electron -- --mode test",
  "build:electron-prod": "npm run build:electron -- --mode production",
  "build:electron:windows-test": "npm run build:electron -- --mode test && cd electron && npm run build:windows",
  "build:electron:windows-prod": "npm run build:electron -- --mode production && cd electron && npm run build:windows",
  "build:electron:mac-dev": "npm run build:electron -- --mode development && cd electron && npm run build:mac",
  "build:electron:mac-test": "npm run build:electron -- --mode test && cd electron && npm run build:mac",
  "build:electron:mac-prod": "npm run build:electron -- --mode production && cd electron && npm run build:mac",
  "build:electron:linux-test": "npm run build:electron -- --mode test && cd electron && npm run build:linux",
  "build:electron:linux-prod": "npm run build:electron -- --mode production && cd electron && npm run build:linux"
}

2.4 Docker Build Scripts

{
  "build:web:docker": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --config vite.config.web.mts && docker build -t timesafari-web .",
  "build:web:docker:test": "npm run build:web:docker -- --mode test",
  "build:web:docker:prod": "npm run build:web:docker -- --mode production"
}

Docker Build Features:

  • Complete Vite build + Docker image creation workflow
  • Environment-specific configurations (test/production)
  • Consistent image tagging (timesafari-web)
  • Mode override flexibility for custom environments

Phase 3: Shell Script Updates (Day 2)

3.1 Update build-electron.sh

  • Add mode-based environment support
  • Update environment loading logic
  • Add environment-specific build paths
  • Update logging to show environment

3.2 Update build-android.sh

  • Add mode-based environment support
  • Update environment detection
  • Add environment-specific configurations

3.3 Update build-ios.sh

  • Add mode-based environment support
  • Update environment detection
  • Add environment-specific configurations

Phase 4: Documentation Updates (Day 2)

4.1 Update BUILDING.md

  • Document new Vite mode-based pattern
  • Update build instructions
  • Add environment-specific examples
  • Update troubleshooting section

4.2 Update scripts/README.md

  • Document new Vite mode-based build patterns
  • Update usage examples
  • Add environment configuration guide

4.3 Update CI/CD Documentation

  • Update GitHub Actions workflows
  • Update Docker build instructions
  • Update deployment guides

Phase 5: Testing & Validation (Day 3)

5.1 Environment Testing

  • Test dev environment builds
  • Test test environment builds
  • Test prod environment builds
  • Validate environment variables

5.2 Platform Testing

  • Test web builds across environments
  • Test capacitor builds across environments
  • Test capacitor android sync across environments
  • Test capacitor ios sync across environments
  • Test electron builds across environments
  • Test electron windows builds across environments
  • Test electron mac builds across environments
  • Test electron linux builds across environments
  • Test electron appimage builds across environments
  • Test electron dmg builds across environments
  • Test docker builds across environments
  • Test docker image creation and tagging
  • Test docker environment-specific configurations

5.3 Integration Testing

  • Test with existing CI/CD pipelines
  • Test with existing deployment scripts
  • Test with existing development workflows

Environment-Specific Configurations

Development Environment (--mode development)

{
  VITE_API_URL: 'http://localhost:3000',
  VITE_DEBUG: 'true',
  VITE_LOG_LEVEL: 'debug',
  VITE_ENABLE_DEV_TOOLS: 'true'
}

Testing Environment (--mode test)

{
  VITE_API_URL: 'https://test-api.timesafari.com',
  VITE_DEBUG: 'false',
  VITE_LOG_LEVEL: 'info',
  VITE_ENABLE_DEV_TOOLS: 'false'
}

Production Environment (--mode production)

{
  VITE_API_URL: 'https://api.timesafari.com',
  VITE_DEBUG: 'false',
  VITE_LOG_LEVEL: 'warn',
  VITE_ENABLE_DEV_TOOLS: 'false'
}

Migration Strategy

Backward Compatibility

  • Keep existing script names as aliases
  • Add deprecation warnings for old scripts
  • Maintain existing CI/CD compatibility
  • Provide migration guide for users

Gradual Rollout

  1. Week 1: Implement new scripts alongside existing ones
  2. Week 2: Update CI/CD to use new pattern
  3. Week 3: Update documentation and guides
  4. Week 4: Deprecate old scripts with warnings

Success Metrics

Technical Metrics

  • All builds work with Vite mode-based pattern
  • Environment variables properly loaded
  • Build artifacts correctly generated
  • No regression in existing functionality

Process Metrics

  • Reduced build script complexity
  • Improved environment management
  • Better developer experience
  • Consistent build patterns

Risk Assessment

Low Risk

  • Environment variable changes
  • Package.json script updates
  • Documentation updates

Medium Risk

  • Vite configuration changes (mode-based)
  • Shell script modifications
  • CI/CD pipeline updates

High Risk

  • Breaking existing build processes
  • Environment-specific bugs
  • Deployment failures

Rollback Plan

Immediate Rollback

  • Revert package.json changes
  • Restore original vite configs
  • Restore original shell scripts

Gradual Rollback

  • Keep old scripts as primary
  • Use new scripts as experimental
  • Gather feedback before full migration

Timeline

Day 1: Foundation

  • Environment configuration setup
  • Package.json script updates
  • Basic testing

Day 2: Integration

  • Shell script updates
  • Documentation updates
  • Integration testing

Day 3: Validation

  • Comprehensive testing
  • Performance validation
  • Documentation review

Day 4: Deployment

  • CI/CD updates
  • Production validation
  • User communication

Next Steps

  1. Review and approve plan
  2. Set up development environment
  3. Begin Phase 1 implementation
  4. Create test cases
  5. Start implementation

Status: Ready for implementation Priority: Medium Estimated Effort: 3-4 days Dependencies: None Stakeholders: Development team, DevOps team