本文档介绍如何将项目部署到生产环境。项目支持多种部署方式,包括静态文件部署、Docker 部署等。
在项目根目录创建 .env.production 文件:
# API 基础路径(生产环境)
VITE_API_URL=https://your-api-domain.com/api/
# 公共路径(根据部署路径配置)
# 如果部署在根目录,使用: /
# 如果部署在子目录,使用: /subdirectory/
VITE_PUBLIC_PATH=/
# 构建输出目录
VITE_DIST_PATH=dist
# 标准生产构建
npm run build
# 或使用 yarn
yarn build
构建完成后,生成的文件位于 dist/ 目录。
构建后的 dist/ 目录结构:
dist/
├── assets/ # 静态资源(JS、CSS、图片等)
│ ├── index.[hash].js
│ ├── index.[hash].css
│ └── ...
├── index.html # 入口 HTML 文件
├── favicon.ico # 网站图标
└── version-build # 版本文件(用于版本检查)
分析构建产物大小,优化打包体积:
# 安装分析插件
npm install --save-dev rollup-plugin-visualizer
# 在 vite.config.ts 中添加配置
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
// ...其他插件
visualizer({
open: true,
gzipSize: true,
brotliSize: true,
}),
],
});
# 构建后会自动打开分析页面
npm run build
项目已配置代码分割(vite.config.ts):
manualChunks: {
vue: ['vue', 'vue-router', 'pinia'],
echarts: ['echarts'],
}
可以根据实际情况调整分割策略。
Vite 默认会压缩代码,可以通过配置进一步优化:
build: {
minify: 'terser', // 使用 terser 压缩(需要安装 terser)
terserOptions: {
compress: {
drop_console: true, // 生产环境移除 console
drop_debugger: true, // 移除 debugger
},
},
}
在部署前,确保正确配置 .env.production:
# API 地址(必须配置为生产环境的后端地址)
VITE_API_URL=https://api.yourdomain.com/api/
# 公共路径
# 根目录部署: /
# 子目录部署: /subdirectory/
VITE_PUBLIC_PATH=/
# 构建输出目录
VITE_DIST_PATH=dist
如果需要支持多个环境(开发、测试、生产),可以创建不同的环境文件:
.env.development - 开发环境.env.staging - 测试环境.env.production - 生产环境构建时指定环境:
# 构建测试环境
vite build --mode staging
# 构建生产环境
vite build --mode production
.env.production)npm run build)# 安装 Certbot
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx
# 获取证书(自动配置 Nginx)
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
# 测试自动续期
sudo certbot renew --dry-run
# 证书会自动续期(通过 cron 任务)
如果使用其他证书提供商:
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL 证书路径
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
# SSL 证书链(如果提供)
# ssl_trusted_certificate /path/to/chain.crt;
# SSL 优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
# HSTS(HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
使用在线工具测试 SSL 配置:
参考上述 Nginx/Apache 配置示例。
压缩效果检查:
# 检查响应头是否包含 Content-Encoding: gzip
curl -H "Accept-Encoding: gzip" -I https://your-domain.com
# 安装 Brotli 模块
# Ubuntu/Debian
sudo apt-get install nginx-module-brotli
# 在 nginx.conf 中加载模块
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
# 配置 Brotli
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# Nginx 示例
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
# 启用压缩
gzip_static on;
brotli_static on;
}
# HTML 文件不缓存
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
}
将静态资源(JS、CSS、图片)部署到 CDN,提升加载速度。
CDN 选择建议:
CDN 配置要点:
项目已配置代码分割(vite.config.ts 中的 manualChunks),将 Vue 核心库和 ECharts 单独打包。
路由懒加载:
// 路由配置中使用动态导入
const routes = [
{
path: '/company',
component: () => import('/@/views/system/company/index.vue'),
},
];
在 index.html 中添加:
<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="https://api.yourdomain.com">
<!-- 预连接 -->
<link rel="preconnect" href="https://api.yourdomain.com">
<!-- 预加载关键资源 -->
<link rel="preload" href="/assets/main.js" as="script">
<link rel="preload" href="/assets/main.css" as="style">
使用性能监控工具:
创建 .github/workflows/deploy.yml:
name: Build and Deploy
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
VITE_API_URL: ${{ secrets.VITE_API_URL }}
VITE_PUBLIC_PATH: ${{ secrets.VITE_PUBLIC_PATH }}
- name: Deploy to server
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
SOURCE: "dist/"
TARGET: "/var/www/zheda-admin/"
创建 .gitlab-ci.yml:
stages:
- build
- deploy
build:
stage: build
image: node:18
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
script:
- scp -r dist/* $DEPLOY_USER@$DEPLOY_HOST:/var/www/zheda-admin/
only:
- main
创建 Jenkinsfile:
pipeline {
agent any
environment {
NODE_VERSION = '18'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('Build') {
steps {
sh 'npm run build'
}
}
stage('Deploy') {
steps {
sh '''
rsync -avz --delete dist/ user@server:/var/www/zheda-admin/
'''
}
}
}
}
创建 /etc/logrotate.d/nginx:
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
使用性能监控工具分析页面性能。
<!-- 在 index.html 中添加 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
</script>
// 监控页面加载性能
window.addEventListener('load', () => {
const perfData = performance.getEntriesByType('navigation')[0];
console.log('DNS查询耗时:', perfData.domainLookupEnd - perfData.domainLookupStart);
console.log('TCP连接耗时:', perfData.connectEnd - perfData.connectStart);
console.log('请求耗时:', perfData.responseEnd - perfData.requestStart);
console.log('DOM解析耗时:', perfData.domContentLoadedEventEnd - perfData.domContentLoadedEventStart);
console.log('页面加载耗时:', perfData.loadEventEnd - perfData.fetchStart);
});
问题: 刷新页面或直接访问路由时出现 404
原因: Web 服务器未配置 SPA 路由支持
解决方案: 参考上述 Nginx/Apache/IIS 配置,确保所有路由都指向 index.html
问题: 前端无法访问后端 API
解决方案:
VITE_API_URL 配置是否正确问题: CSS、JS 文件加载失败
解决方案:
VITE_PUBLIC_PATH 配置是否正确问题: 用户浏览器缓存了旧版本
解决方案:
可以配置更激进的缓存策略,确保 HTML 文件不被缓存
# HTML 文件不缓存
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# 创建备份脚本 backup.sh
#!/bin/bash
BACKUP_DIR="/backup/zheda-admin"
DATE=$(date +%Y%m%d_%H%M%S)
DEPLOY_DIR="/var/www/zheda-admin"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 备份部署文件
tar -czf $BACKUP_DIR/zheda-admin_$DATE.tar.gz -C $DEPLOY_DIR .
# 保留最近 7 天的备份
find $BACKUP_DIR -name "zheda-admin_*.tar.gz" -mtime +7 -delete
echo "备份完成: $BACKUP_DIR/zheda-admin_$DATE.tar.gz"
使用 cron 定时任务:
# 编辑 crontab
crontab -e
# 每天凌晨 2 点备份
0 2 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1
# 停止服务(如果需要)
sudo systemctl stop nginx
# 恢复备份
cd /var/www/zheda-admin
tar -xzf /backup/zheda-admin_20240101_020000.tar.gz
# 重启服务
sudo systemctl start nginx
# 验证恢复
curl -I https://your-domain.com
使用 Git 标签管理版本:
# 创建版本标签
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.0
# 查看所有标签
git tag
# 切换到指定版本
git checkout v1.0.0
如果部署后出现问题,可以快速回滚:
部署前备份当前版本:
# 部署前备份
cp -r /var/www/zheda-admin /var/www/zheda-admin.backup.$(date +%Y%m%d_%H%M%S)
# 部署新版本
rsync -avz --delete dist/ /var/www/zheda-admin/
# 如果出现问题,快速回滚
rm -rf /var/www/zheda-admin
cp -r /var/www/zheda-admin.backup.* /var/www/zheda-admin
# 查看提交历史
git log --oneline
# 回滚到指定版本
git checkout <commit-hash>
npm run build
# 重新部署
rsync -avz --delete dist/ /var/www/zheda-admin/
使用蓝绿部署策略,实现零停机回滚:
# 部署到绿色环境
rsync -avz --delete dist/ /var/www/zheda-admin-green/
# 测试绿色环境
curl https://green.your-domain.com
# 切换流量(更新 Nginx 配置)
sudo nginx -s reload
# 如果出现问题,立即切换回蓝色环境