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.
371 lines
11 KiB
371 lines
11 KiB
#!/bin/bash
|
|
# build-web.sh
|
|
# Author: Matthew Raymer
|
|
# Description: Web build script for TimeSafari application
|
|
# This script handles the complete web build process including cleanup,
|
|
# environment setup, Vite build, and optional Docker containerization.
|
|
#
|
|
# Usage:
|
|
# ./scripts/build-web.sh # Development build
|
|
# ./scripts/build-web.sh --dev # Development build (explicit)
|
|
# ./scripts/build-web.sh --test # Test environment build
|
|
# ./scripts/build-web.sh --prod # Production environment build
|
|
# ./scripts/build-web.sh --docker # Build with Docker containerization
|
|
# ./scripts/build-web.sh --docker:test # Test environment + Docker
|
|
# ./scripts/build-web.sh --docker:prod # Production environment + Docker
|
|
# ./scripts/build-web.sh --serve # Build and serve locally
|
|
# ./scripts/build-web.sh --help # Show help
|
|
# ./scripts/build-web.sh --verbose # Enable verbose logging
|
|
#
|
|
# NPM Script Equivalents:
|
|
# npm run build:web # Development build
|
|
# npm run build:web:test # Test environment build
|
|
# npm run build:web:prod # Production environment build
|
|
# npm run build:web:docker # Docker build
|
|
# npm run build:web:docker:test # Test Docker build
|
|
# npm run build:web:docker:prod # Production Docker build
|
|
#
|
|
# Exit Codes:
|
|
# 1 - Web cleanup failed
|
|
# 2 - Environment setup failed
|
|
# 3 - Vite build failed
|
|
# 4 - Docker build failed
|
|
# 5 - Serve command failed
|
|
# 6 - Invalid build mode
|
|
|
|
# Exit on any error
|
|
set -e
|
|
|
|
# Source common utilities
|
|
source "$(dirname "$0")/common.sh"
|
|
|
|
# Default values
|
|
BUILD_MODE="development"
|
|
BUILD_ACTION="build"
|
|
DOCKER_BUILD=false
|
|
SERVE_BUILD=false
|
|
|
|
# Function to show usage
|
|
show_usage() {
|
|
cat << EOF
|
|
Usage: $0 [OPTIONS]
|
|
|
|
OPTIONS:
|
|
--dev, --development Build for development environment (default)
|
|
--test Build for test environment
|
|
--prod, --production Build for production environment
|
|
--docker Build and create Docker container
|
|
--docker:test Build for test environment and create Docker container
|
|
--docker:prod Build for production environment and create Docker container
|
|
--serve Build and serve locally
|
|
--help Show this help message
|
|
--verbose Enable verbose logging
|
|
--env Show environment variables
|
|
|
|
EXAMPLES:
|
|
$0 # Development build
|
|
$0 --test # Test environment build
|
|
$0 --prod # Production environment build
|
|
$0 --docker # Development + Docker
|
|
$0 --docker:test # Test + Docker
|
|
$0 --docker:prod # Production + Docker
|
|
$0 --serve # Build and serve
|
|
|
|
BUILD MODES:
|
|
development: Starts Vite development server with hot reload (default)
|
|
test: Optimized for testing with minimal minification
|
|
production: Optimized for production with full minification and optimization
|
|
|
|
EOF
|
|
}
|
|
|
|
# Function to parse web-specific arguments
|
|
parse_web_args() {
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--dev|--development)
|
|
BUILD_MODE="development"
|
|
shift
|
|
;;
|
|
--test)
|
|
BUILD_MODE="test"
|
|
shift
|
|
;;
|
|
--prod|--production)
|
|
BUILD_MODE="production"
|
|
shift
|
|
;;
|
|
--docker)
|
|
DOCKER_BUILD=true
|
|
shift
|
|
;;
|
|
--docker:test)
|
|
BUILD_MODE="test"
|
|
DOCKER_BUILD=true
|
|
shift
|
|
;;
|
|
--docker:prod)
|
|
BUILD_MODE="production"
|
|
DOCKER_BUILD=true
|
|
shift
|
|
;;
|
|
--serve)
|
|
SERVE_BUILD=true
|
|
shift
|
|
;;
|
|
--help)
|
|
show_usage
|
|
exit 0
|
|
;;
|
|
--verbose)
|
|
VERBOSE=true
|
|
shift
|
|
;;
|
|
--env)
|
|
print_env_vars "VITE_"
|
|
exit 0
|
|
;;
|
|
*)
|
|
log_warn "Unknown option: $1"
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# Function to validate web build environment
|
|
validate_web_environment() {
|
|
log_info "Validating web build environment..."
|
|
|
|
# Check if Node.js is available
|
|
if ! check_command "node"; then
|
|
log_error "Node.js is required but not installed"
|
|
exit 2
|
|
fi
|
|
|
|
# Check if npm is available
|
|
if ! check_command "npm"; then
|
|
log_error "npm is required but not installed"
|
|
exit 2
|
|
fi
|
|
|
|
# Check if Vite is available
|
|
if ! check_command "npx"; then
|
|
log_error "npx is required but not installed"
|
|
exit 2
|
|
fi
|
|
|
|
# Check if package.json exists
|
|
if ! check_file "package.json"; then
|
|
log_error "package.json not found in current directory"
|
|
exit 2
|
|
fi
|
|
|
|
log_success "Web build environment validated"
|
|
}
|
|
|
|
# Function to setup web-specific environment
|
|
setup_web_environment() {
|
|
log_info "Setting up web environment for $BUILD_MODE mode..."
|
|
|
|
# Set NODE_ENV based on build mode
|
|
case $BUILD_MODE in
|
|
"production")
|
|
export NODE_ENV="production"
|
|
;;
|
|
"test")
|
|
export NODE_ENV="test"
|
|
;;
|
|
"development"|*)
|
|
export NODE_ENV="development"
|
|
;;
|
|
esac
|
|
|
|
# Load environment-specific .env file if it exists
|
|
local env_file=".env.$BUILD_MODE"
|
|
if [ -f "$env_file" ]; then
|
|
load_env_file "$env_file"
|
|
else
|
|
log_debug "No $env_file file found, using default environment"
|
|
fi
|
|
|
|
# Load .env file if it exists (fallback)
|
|
if [ -f ".env" ]; then
|
|
load_env_file ".env"
|
|
fi
|
|
|
|
log_success "Web environment configured for $BUILD_MODE mode"
|
|
log_debug "NODE_ENV=$NODE_ENV"
|
|
}
|
|
|
|
# Function to execute Vite build
|
|
execute_vite_build() {
|
|
local mode="$1"
|
|
log_info "Executing Vite build for $mode mode..."
|
|
|
|
# Construct Vite build command
|
|
local vite_cmd="VITE_GIT_HASH=\$(git log -1 --pretty=format:%h) npx vite build --config vite.config.web.mts"
|
|
|
|
# Add mode if not development (development is default)
|
|
if [ "$mode" != "development" ]; then
|
|
vite_cmd="$vite_cmd --mode $mode"
|
|
fi
|
|
|
|
log_debug "Vite command: $vite_cmd"
|
|
|
|
if ! measure_time eval "$vite_cmd"; then
|
|
log_error "Vite build failed for $mode mode!"
|
|
exit 3
|
|
fi
|
|
|
|
log_success "Vite build completed for $mode mode"
|
|
}
|
|
|
|
# Function to execute Docker build
|
|
execute_docker_build() {
|
|
local mode="$1"
|
|
log_info "Executing Docker build for $mode mode..."
|
|
|
|
# Build Docker image with appropriate tags
|
|
local docker_cmd="docker build"
|
|
local image_tag="timesafari-web"
|
|
|
|
# Add build arguments
|
|
docker_cmd="$docker_cmd --build-arg BUILD_MODE=$mode"
|
|
docker_cmd="$docker_cmd --build-arg NODE_ENV=$NODE_ENV"
|
|
|
|
# Add image tag
|
|
docker_cmd="$docker_cmd -t $image_tag:$mode"
|
|
docker_cmd="$docker_cmd -t $image_tag:latest"
|
|
|
|
# Add context
|
|
docker_cmd="$docker_cmd ."
|
|
|
|
log_debug "Docker command: $docker_cmd"
|
|
|
|
if ! measure_time eval "$docker_cmd"; then
|
|
log_error "Docker build failed for $mode mode!"
|
|
exit 4
|
|
fi
|
|
|
|
log_success "Docker build completed for $mode mode"
|
|
log_info "Docker image available as: $image_tag:$mode"
|
|
}
|
|
|
|
# Function to start Vite development server
|
|
start_dev_server() {
|
|
log_info "Starting Vite development server..."
|
|
|
|
# Construct Vite dev server command
|
|
local vite_cmd="VITE_GIT_HASH=\$(git log -1 --pretty=format:%h) npx vite --config vite.config.web.mts"
|
|
|
|
# Add mode if specified (though development is default)
|
|
if [ "$BUILD_MODE" != "development" ]; then
|
|
vite_cmd="$vite_cmd --mode $BUILD_MODE"
|
|
fi
|
|
|
|
log_debug "Vite dev server command: $vite_cmd"
|
|
log_info "Starting development server on http://localhost:8080"
|
|
|
|
# Start the development server (this will block and run the server)
|
|
eval "$vite_cmd"
|
|
}
|
|
|
|
# Function to serve build locally
|
|
serve_build() {
|
|
log_info "Serving build locally..."
|
|
|
|
# Check if dist directory exists
|
|
if [ ! -d "dist" ]; then
|
|
log_error "dist directory not found. Build must be completed first."
|
|
exit 5
|
|
fi
|
|
|
|
# Use a simple HTTP server to serve the build
|
|
if command -v python3 &> /dev/null; then
|
|
log_info "Starting Python HTTP server on port 8080..."
|
|
cd dist && python3 -m http.server 8080
|
|
elif command -v python &> /dev/null; then
|
|
log_info "Starting Python HTTP server on port 8080..."
|
|
cd dist && python -m SimpleHTTPServer 8080
|
|
elif command -v npx &> /dev/null; then
|
|
log_info "Starting npx serve on port 8080..."
|
|
npx serve -s dist -l 8080
|
|
else
|
|
log_error "No suitable HTTP server found. Install Python or npx serve."
|
|
exit 5
|
|
fi
|
|
}
|
|
|
|
# Parse command line arguments
|
|
parse_web_args "$@"
|
|
|
|
# Print build header
|
|
print_header "TimeSafari Web Build Process"
|
|
log_info "Starting web build process at $(date)"
|
|
log_info "Build mode: $BUILD_MODE"
|
|
log_info "Docker build: $DOCKER_BUILD"
|
|
log_info "Serve build: $SERVE_BUILD"
|
|
|
|
# Validate environment
|
|
validate_web_environment
|
|
|
|
# Setup environment for web build
|
|
setup_build_env "web"
|
|
|
|
# Setup application directories
|
|
setup_app_directories
|
|
|
|
# Setup web-specific environment
|
|
setup_web_environment
|
|
|
|
# Handle different build modes
|
|
if [ "$BUILD_MODE" = "development" ] && [ "$DOCKER_BUILD" = false ] && [ "$SERVE_BUILD" = false ]; then
|
|
# Development mode: Start dev server
|
|
log_info "Development mode detected - starting development server"
|
|
start_dev_server
|
|
# Note: start_dev_server doesn't return, it runs the server
|
|
elif [ "$SERVE_BUILD" = true ]; then
|
|
# Serve mode: Build then serve
|
|
log_info "Serve mode detected - building then serving"
|
|
|
|
# Step 1: Clean dist directory
|
|
log_info "Cleaning dist directory..."
|
|
clean_build_artifacts "dist"
|
|
|
|
# Step 2: Execute Vite build
|
|
safe_execute "Vite build for $BUILD_MODE mode" "execute_vite_build $BUILD_MODE" || exit 3
|
|
|
|
# Step 3: Serve the build
|
|
log_info "Starting local server..."
|
|
serve_build
|
|
# Note: serve_build doesn't return, it starts the server
|
|
else
|
|
# Build mode: Build (and optionally Docker)
|
|
log_info "Build mode detected - building for $BUILD_MODE"
|
|
|
|
# Step 1: Clean dist directory
|
|
log_info "Cleaning dist directory..."
|
|
clean_build_artifacts "dist"
|
|
|
|
# Step 2: Execute Vite build
|
|
safe_execute "Vite build for $BUILD_MODE mode" "execute_vite_build $BUILD_MODE" || exit 3
|
|
|
|
# Step 3: Execute Docker build if requested
|
|
if [ "$DOCKER_BUILD" = true ]; then
|
|
safe_execute "Docker build for $BUILD_MODE mode" "execute_docker_build $BUILD_MODE" || exit 4
|
|
fi
|
|
|
|
# Print build summary
|
|
log_success "Web build completed successfully!"
|
|
log_info "Build output available in: dist/"
|
|
|
|
if [ "$DOCKER_BUILD" = true ]; then
|
|
log_info "Docker image available as: timesafari-web:$BUILD_MODE"
|
|
fi
|
|
|
|
print_footer "Web Build"
|
|
|
|
# Exit with success
|
|
exit 0
|
|
fi
|