feat: 添加完整的部署支持
- 后端多环境配置(dev, prod) - Docker 部署支持(Dockerfile, docker-compose.yml) - Java 部署脚本(deploy.sh) - 前端构建脚本(build.sh,支持自定义后端地址) - 健康检查接口(/api/health) - 完整的部署文档(docs/DEPLOYMENT.md) - 前端环境变量支持(VITE_API_URL, VITE_WS_URL)
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# 依赖
|
||||
node_modules/
|
||||
.pnpm-store/
|
||||
|
||||
# 构建产物
|
||||
dist/
|
||||
build/
|
||||
out/
|
||||
|
||||
# 环境配置
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
|
||||
# 日志
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# 其他
|
||||
*.bak
|
||||
*.backup
|
||||
*.old
|
||||
|
||||
Executable
+137
@@ -0,0 +1,137 @@
|
||||
#!/bin/bash
|
||||
|
||||
# PolyHermes 前端构建脚本
|
||||
# 支持自定义后端 API 地址
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 默认配置
|
||||
DEFAULT_API_URL="http://127.0.0.1:8000"
|
||||
API_URL="${VITE_API_URL:-$DEFAULT_API_URL}"
|
||||
|
||||
# 打印信息
|
||||
info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# 检查 Node.js 环境
|
||||
check_node() {
|
||||
if ! command -v node &> /dev/null; then
|
||||
error "Node.js 未安装,请先安装 Node.js 18+"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
||||
if [ "$NODE_VERSION" -lt 18 ]; then
|
||||
error "Node.js 版本过低,需要 Node.js 18+,当前版本: $(node -v)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
info "Node.js 环境检查通过: $(node -v)"
|
||||
}
|
||||
|
||||
# 创建环境配置文件
|
||||
create_env_file() {
|
||||
info "创建环境配置文件..."
|
||||
|
||||
# 解析 API URL,提取协议、主机和端口
|
||||
if [[ $API_URL == http* ]]; then
|
||||
# 提取协议和主机
|
||||
PROTOCOL=$(echo $API_URL | sed -E 's|^([^:]+)://.*|\1|')
|
||||
HOST_PORT=$(echo $API_URL | sed -E 's|^[^:]+://([^/]+).*|\1|')
|
||||
HOST=$(echo $HOST_PORT | cut -d':' -f1)
|
||||
PORT=$(echo $HOST_PORT | cut -d':' -f2)
|
||||
|
||||
# 构建 WebSocket URL
|
||||
if [ "$PROTOCOL" = "https" ]; then
|
||||
WS_PROTOCOL="wss"
|
||||
else
|
||||
WS_PROTOCOL="ws"
|
||||
fi
|
||||
WS_URL="${WS_PROTOCOL}://${HOST}:${PORT}"
|
||||
else
|
||||
error "API URL 格式错误,应为 http://host:port 或 https://host:port"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建 .env.production 文件
|
||||
cat > .env.production <<EOF
|
||||
# 后端 API 地址
|
||||
VITE_API_URL=$API_URL
|
||||
VITE_WS_URL=$WS_URL
|
||||
EOF
|
||||
|
||||
info "环境配置已创建: .env.production"
|
||||
info " API URL: $API_URL"
|
||||
info " WebSocket URL: $WS_URL"
|
||||
}
|
||||
|
||||
# 构建应用
|
||||
build_app() {
|
||||
info "开始构建前端应用..."
|
||||
|
||||
# 检查依赖
|
||||
if [ ! -d "node_modules" ]; then
|
||||
info "安装依赖..."
|
||||
npm install
|
||||
fi
|
||||
|
||||
# 构建
|
||||
info "执行构建..."
|
||||
npm run build
|
||||
|
||||
if [ ! -d "dist" ]; then
|
||||
error "构建失败,dist 目录不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
info "构建完成: dist/"
|
||||
info "构建产物大小: $(du -sh dist | cut -f1)"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
echo "=========================================="
|
||||
echo " PolyHermes 前端构建脚本"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
check_node
|
||||
|
||||
# 解析参数
|
||||
if [ "$1" = "--api-url" ] && [ -n "$2" ]; then
|
||||
API_URL="$2"
|
||||
info "使用自定义 API 地址: $API_URL"
|
||||
elif [ -n "$VITE_API_URL" ]; then
|
||||
info "使用环境变量 API 地址: $API_URL"
|
||||
else
|
||||
info "使用默认 API 地址: $API_URL"
|
||||
warn "提示: 可通过环境变量 VITE_API_URL 或参数 --api-url 自定义后端地址"
|
||||
fi
|
||||
|
||||
create_env_file
|
||||
build_app
|
||||
|
||||
echo ""
|
||||
info "构建完成!"
|
||||
info "部署方式:"
|
||||
info " 1. 静态文件服务器:将 dist/ 目录部署到 Nginx、Apache 等"
|
||||
info " 2. 使用 serve 预览:npx serve -s dist -l 3000"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -5,9 +5,22 @@ import { wsManager } from './websocket'
|
||||
|
||||
/**
|
||||
* API 基础配置
|
||||
* 支持通过环境变量 VITE_API_URL 配置后端地址
|
||||
* 默认使用相对路径 /api(适用于同域部署)
|
||||
* 如果设置了 VITE_API_URL,则使用完整 URL
|
||||
*/
|
||||
const getBaseURL = (): string => {
|
||||
const envApiUrl = import.meta.env.VITE_API_URL
|
||||
if (envApiUrl) {
|
||||
// 如果设置了环境变量,使用完整 URL
|
||||
return `${envApiUrl}/api`
|
||||
}
|
||||
// 否则使用相对路径(适用于开发环境代理或同域部署)
|
||||
return '/api'
|
||||
}
|
||||
|
||||
const apiClient: AxiosInstance = axios.create({
|
||||
baseURL: '/api',
|
||||
baseURL: getBaseURL(),
|
||||
timeout: 30000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
|
||||
@@ -325,16 +325,28 @@ class WebSocketManager {
|
||||
|
||||
/**
|
||||
* 获取 WebSocket URL(带token认证)
|
||||
* 支持通过环境变量 VITE_WS_URL 配置 WebSocket 地址
|
||||
*/
|
||||
private getWebSocketUrl(): string {
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
const host = window.location.host
|
||||
const envWsUrl = import.meta.env.VITE_WS_URL
|
||||
let wsBaseUrl: string
|
||||
|
||||
if (envWsUrl) {
|
||||
// 如果设置了环境变量,使用完整 URL
|
||||
wsBaseUrl = envWsUrl
|
||||
} else {
|
||||
// 否则使用相对路径(适用于开发环境代理或同域部署)
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
const host = window.location.host
|
||||
wsBaseUrl = `${protocol}//${host}`
|
||||
}
|
||||
|
||||
const token = this.getToken()
|
||||
if (token) {
|
||||
// 通过查询参数传递token
|
||||
return `${protocol}//${host}/ws?token=${encodeURIComponent(token)}`
|
||||
return `${wsBaseUrl}/ws?token=${encodeURIComponent(token)}`
|
||||
}
|
||||
return `${protocol}//${host}/ws`
|
||||
return `${wsBaseUrl}/ws`
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_URL?: string
|
||||
readonly VITE_WS_URL?: string
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv
|
||||
}
|
||||
|
||||
+29
-14
@@ -1,21 +1,36 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
server: {
|
||||
port: 3000,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:8000',
|
||||
changeOrigin: true
|
||||
},
|
||||
'/ws': {
|
||||
target: 'ws://localhost:8000',
|
||||
ws: true,
|
||||
changeOrigin: true
|
||||
export default defineConfig(({ mode }) => {
|
||||
// 加载环境变量
|
||||
const env = loadEnv(mode, process.cwd(), '')
|
||||
|
||||
// 从环境变量获取 API 地址,默认使用 localhost:8000
|
||||
const API_URL = env.VITE_API_URL || 'http://localhost:8000'
|
||||
const WS_URL = env.VITE_WS_URL || 'ws://localhost:8000'
|
||||
|
||||
return {
|
||||
plugins: [react()],
|
||||
server: {
|
||||
port: 3000,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: API_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '/api')
|
||||
},
|
||||
'/ws': {
|
||||
target: WS_URL,
|
||||
ws: true,
|
||||
changeOrigin: true
|
||||
}
|
||||
}
|
||||
},
|
||||
// 定义环境变量,在构建时注入
|
||||
define: {
|
||||
'import.meta.env.VITE_API_URL': JSON.stringify(API_URL),
|
||||
'import.meta.env.VITE_WS_URL': JSON.stringify(WS_URL)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user