#!/usr/bin/env bash # ============================================================================= # 07-start-frontend.sh — 启动前端开发服务器 # # 用法: # ./07-start-frontend.sh # 启动全部前端项目 # ./07-start-frontend.sh # 只启动指定项目 # # 项目与端口: # pc → Electron + Vite :7777 # meetingh5 → React + Vite :5188 # h5 → Vue + Vite :3003 # cms → UMI Max :8001 # build-cms → UMI Max :8002 # build-down → UMI v3 :8003 # # 日志文件: .local-dev/logs/fe-.log # PID 文件: .local-dev/pids/fe-.pid # ============================================================================= set -euo pipefail source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" init_dirs init_script_log # ← 脚本执行日志 header "启动前端开发服务器" # ── 前端服务配置 ────────────────────────────────────────────────────────────── # name → (目录, 包管理器, 启动命令, 环境变量, 端口描述) declare -A FE_DIR=( [pc]="pc" [meetingh5]="meetingh5" [h5]="h5" [cms]="cms" [build-cms]="build-cms" [build-down]="build-down" ) declare -A FE_PM=( [pc]="yarn" [meetingh5]="npm" [h5]="npm" [cms]="pnpm" [build-cms]="pnpm" [build-down]="npm" ) declare -A FE_CMD=( [pc]="yarn dev" [meetingh5]="npm run dev" [h5]="npm run dev" [cms]="pnpm run dev" [build-cms]="pnpm run dev" [build-down]="npm run dev" ) # cms/build-cms/build-down 不配置端口时默认都是 8000,需手动指定 declare -A FE_ENV=( [pc]="" [meetingh5]="" [h5]="" [cms]="PORT=8001" [build-cms]="PORT=8002" [build-down]="PORT=8003" ) declare -A FE_PORT=( [pc]=":7777 (Electron Vite 调试服务器)" [meetingh5]=":5188" [h5]=":3003" [cms]=":8001" [build-cms]=":8002" [build-down]=":8003" ) # ── 启动单个前端服务 ────────────────────────────────────────────────────────── _start_fe() { local name="$1" local dir="$ROOT_DIR/${FE_DIR[$name]}" local pm="${FE_PM[$name]}" local cmd="${FE_CMD[$name]}" local env_prefix="${FE_ENV[$name]}" local pidfile="$PID_DIR/fe-${name}.pid" local logfile="$LOG_DIR/fe-${name}.log" # 已在运行 if [[ -f "$pidfile" ]] && kill -0 "$(cat "$pidfile")" 2>/dev/null; then warn "$name 已在运行 (PID=$(cat "$pidfile")),跳过" return 0 fi # 目录检查 if [[ ! -d "$dir" ]]; then warn "$name 目录不存在 ($dir),跳过" return 0 fi # 依赖检查 if [[ ! -d "$dir/node_modules" ]]; then warn "$name node_modules 不存在,请先执行: ./deploy-test/06-install-frontend.sh $name" return 1 fi # 包管理器检查 if ! command -v "$pm" &>/dev/null; then error "$name 需要 $pm,未安装" return 1 fi info "启动 ${BOLD}$name${NC} ..." # 写日志分隔符 { echo "" echo "──── 启动 $(date '+%Y-%m-%d %H:%M:%S') ────" } >> "$logfile" # 后台启动(带环境变量前缀) ( cd "$dir" if [[ -n "$env_prefix" ]]; then # shellcheck disable=SC2086 nohup env $env_prefix $cmd >> "$logfile" 2>&1 & else # shellcheck disable=SC2086 nohup $cmd >> "$logfile" 2>&1 & fi echo $! > "$pidfile" ) sleep 2 if [[ -f "$pidfile" ]] && kill -0 "$(cat "$pidfile")" 2>/dev/null; then success " ✓ $name (PID=$(cat "$pidfile")) ${FE_PORT[$name]} → $logfile" else error " ✗ $name 启动失败,查看日志:" tail -20 "$logfile" 2>/dev/null || true return 1 fi } # ── 入口 ───────────────────────────────────────────────────────────────────── TARGET="${1:-all}" FE_PROJECTS=(pc meetingh5 h5 cms build-cms build-down) _all_valid() { for p in "${FE_PROJECTS[@]}"; do [[ "$p" == "$1" ]] && return 0 done return 1 } if [[ "$TARGET" == "all" ]]; then step "启动全部前端开发服务器" FAILED=() for proj in "${FE_PROJECTS[@]}"; do _start_fe "$proj" || FAILED+=("$proj") done echo "" echo -e "${BOLD}前端服务汇总:${NC}" for proj in "${FE_PROJECTS[@]}"; do local_pidfile="$PID_DIR/fe-${proj}.pid" if [[ -f "$local_pidfile" ]] && kill -0 "$(cat "$local_pidfile")" 2>/dev/null; then printf " ${GREEN}●${NC} %-14s PID=%-7s %s\n" "$proj" "$(cat "$local_pidfile")" "${FE_PORT[$proj]}" else printf " ${RED}○${NC} %-14s 未运行 %s\n" "$proj" "${FE_PORT[$proj]}" fi done echo "" echo -e "${BOLD}访问地址:${NC}" echo " PC (Electron): yarn dev 启动后自动打开窗口" echo " H5: http://${DEPLOY_TEST_IP}:3003" echo " CMS: http://${DEPLOY_TEST_IP}:8001" echo " Build CMS: http://${DEPLOY_TEST_IP}:8002" echo " Build Download: http://${DEPLOY_TEST_IP}:8003" echo "" echo -e "${BOLD}MeetingH5 访问地址(后端 URL 由 .env.local 默认设置,也可通过 URL 参数覆盖):${NC}" echo " 默认: http://${DEPLOY_TEST_IP}:5188" echo " 显式指定后端: http://${DEPLOY_TEST_IP}:5188?ws=ws://${DEPLOY_TEST_IP}:8000&liveApi=http://${DEPLOY_TEST_IP}:8081" echo " 说明: ws → meetingmsg 弹幕 WebSocket (:8000)" echo " liveApi → livestream 直播间 API (:8081)" if [[ ${#FAILED[@]} -gt 0 ]]; then echo "" warn "以下项目启动失败: ${FAILED[*]}" echo " 可能原因: node_modules 未安装,执行: ./deploy-test/06-install-frontend.sh" fi else if ! _all_valid "$TARGET"; then error "未知项目: $TARGET" echo "可用: ${FE_PROJECTS[*]}" exit 1 fi step "启动前端项目: $TARGET" _start_fe "$TARGET" fi