forked from jsnbuchanan/crowd-funder-for-time-pwa
- Add PWAInstallPrompt component for custom install UI and event handling - Register PWAInstallPrompt in App.vue for global visibility - Enable PWA features and install prompt in dev, test, and prod (vite.config.web.mts) - Update service worker registration to work in all environments - Update docs/build-web-script-integration.md with PWA install guidance and visual cues - Add scripts/build-web.sh for unified web build/dev workflow PWA is now installable and testable in all web environments, with clear user prompts and desktop support.
371 lines
11 KiB
Bash
Executable File
371 lines
11 KiB
Bash
Executable File
#!/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 |