Skip to content

Vue3 + Vite 项目的前端打包部署最佳实践

现代前端应用(尤其是使用 Vue3 和 Vite 构建的项目)的部署,需要根据不同的场景采用相应的策略。本文将针对四种常见部署场景进行深入分析,每个场景分别讨论构建位置选择、CI/CD 自动化流程、版本管理与回滚、缓存优化,以及安全与权限配置等方面的最佳实践。

目录


场景一:静态托管平台

概述

静态托管平台(如 Vercel、Netlify、GitHub Pages)是最简单的前端部署方案,适合大多数 Vue3 + Vite 项目。

构建过程

推荐:平台云端构建

  • 将代码推送到 Git 仓库后,平台自动拉取代码、安装依赖、执行 npm run build
  • 无需在本地手动产出构建文件并上传
  • 避免人工步骤和环境差异的影响

本地构建用途:

  • 预先测试产物,确保构建后应用能正常运行
  • 开发调试和预发布演练

CI/CD 自动化流程

Vercel/Netlify

yaml
# 自动触发条件
- 代码推送到主分支
- 创建 Pull Request(生成预览链接)
- 合并到主分支(触发正式部署)

特点:

  • 智能识别 Vite 项目并使用默认命令构建
  • 全球 CDN 自动部署
  • 预览部署功能
  • 零配置即可使用

GitHub Pages

yaml
# .github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - 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

      - name: Deploy to GitHub Pages
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          folder: dist
          token: ${{ secrets.GITHUB_TOKEN }}

版本管理与回滚

平台版本管理

  • 每次部署生成唯一版本标识
  • 一键回滚功能
  • 原子性部署,旧版本资源保留

前端资源版本化

javascript
// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        // 自动生成内容哈希
        entryFileNames: "assets/[name].[hash].js",
        chunkFileNames: "assets/[name].[hash].js",
        assetFileNames: "assets/[name].[hash].[ext]",
      },
    },
  },
});

缓存优化策略

1. 文件名哈希化

javascript
// Vite 默认配置
// app.abc123.js (内容变化时哈希自动更新)
// style.def456.css

2. Cache-Control 配置

javascript
// 静态资源:长期缓存
Cache-Control: max-age=31536000, immutable

// HTML 文件:不缓存或短缓存
Cache-Control: no-cache

3. Service Worker(可选)

javascript
// vite.config.js
import { VitePWA } from "vite-plugin-pwa";

export default defineConfig({
  plugins: [
    VitePWA({
      registerType: "autoUpdate",
      workbox: {
        globPatterns: ["**/*.{js,css,html,ico,png,svg}"],
      },
    }),
  ],
});

安全与权限配置

敏感信息管理

javascript
// ❌ 错误做法
const API_KEY = "sk-1234567890"; // 不要硬编码

// ✅ 正确做法
const API_KEY = import.meta.env.VITE_API_KEY;

平台配置

  • 开启强制 HTTPS
  • 配置自定义域名 SSL 证书
  • 设置安全响应头
  • 控制部署权限

场景二:云服务器部署

概述

自管服务器(如阿里云 ECS、腾讯云主机、自有 VPS)提供更高的控制权,适合需要自定义配置的项目。

构建过程

推荐:CI 构建 + 文件部署

bash
# 不推荐:在服务器上直接构建
# 原因:环境复杂、安全风险、资源消耗

# 推荐:CI 构建后部署
本地/CI 构建 上传 dist/ 服务器运行

CI/CD 流水线设计

GitHub Actions 示例

yaml
name: Deploy to Server

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - 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

      - name: Deploy to server
        uses: appleboy/ssh-action@v0.1.5
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            cd /var/www/myapp
            rm -rf dist
            # 新文件通过 rsync 上传

部署脚本

bash
#!/bin/bash
# deploy.sh

# 1. 备份当前版本
cp -r /var/www/myapp /var/www/myapp.backup.$(date +%Y%m%d_%H%M%S)

# 2. 上传新版本
rsync -avz --delete dist/ user@server:/var/www/myapp/

# 3. 重载 Nginx
ssh user@server "sudo nginx -s reload"

# 4. 健康检查
curl -f http://your-domain.com || exit 1

版本管理与回滚

版本化目录部署

bash
# 目录结构
/var/www/myapp/
├── 2025-01-27-build123/  # 版本目录
├── 2025-01-26-build122/
├── current -> 2025-01-27-build123/  # 符号链接
└── nginx.conf

Nginx 配置

nginx
server {
    listen 80;
    server_name your-domain.com;

    # 指向当前版本
    root /var/www/myapp/current;
    index index.html;

    # SPA 路由支持
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

回滚脚本

bash
#!/bin/bash
# rollback.sh

VERSION=$1
if [ -z "$VERSION" ]; then
    echo "Usage: ./rollback.sh <version>"
    exit 1
fi

# 切换到指定版本
ln -sfn /var/www/myapp/$VERSION /var/www/myapp/current

# 重载 Nginx
sudo nginx -s reload

echo "Rolled back to version: $VERSION"

缓存优化策略

Nginx 缓存配置

nginx
server {
    # Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/javascript application/json;
    gzip_min_length 1000;

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header Vary "Accept-Encoding";
    }

    # HTML 文件不缓存
    location ~* \.html$ {
        expires -1;
        add_header Cache-Control "no-cache, no-store, must-revalidate";
    }
}

安全与权限配置

服务器安全

bash
# 1. 防火墙配置
sudo ufw allow 22    # SSH
sudo ufw allow 80    # HTTP
sudo ufw allow 443   # HTTPS
sudo ufw enable

# 2. SSH 安全
# 禁用密码登录,使用密钥认证
sudo nano /etc/ssh/sshd_config
# PasswordAuthentication no
# PubkeyAuthentication yes

# 3. 文件权限
sudo chown -R www-data:www-data /var/www/myapp
sudo chmod -R 755 /var/www/myapp

Nginx 安全配置

nginx
server {
    # 隐藏版本信息
    server_tokens off;

    # 安全响应头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
    }

    # SSL 配置
    listen 443 ssl http2;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
}

场景三:容器化部署

概述

容器化部署(Docker + Nginx)提供环境一致性,适合微服务架构和云原生应用。

构建过程

Docker 多阶段构建

dockerfile
# Dockerfile
# 第一阶段:构建
FROM node:18-alpine AS build

WORKDIR /app

# 复制依赖文件
COPY package*.json ./
RUN npm ci --only=production

# 复制源代码
COPY . .

# 构建应用
RUN npm run build

# 第二阶段:运行
FROM nginx:alpine

# 复制构建产物
COPY --from=build /app/dist /usr/share/nginx/html

# 复制 Nginx 配置
COPY nginx.conf /etc/nginx/conf.d/default.conf

# 暴露端口
EXPOSE 80

# 启动命令
CMD ["nginx", "-g", "daemon off;"]

Nginx 配置

nginx
# nginx.conf
server {
    listen 80;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.html;

    # SPA 路由支持
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/javascript application/json;
}

CI/CD 自动化流程

GitHub Actions

yaml
name: Build and Deploy Docker

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: |
            your-username/vue-app:latest
            your-username/vue-app:${{ github.sha }}

      - name: Deploy to server
        uses: appleboy/ssh-action@v0.1.5
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            docker pull your-username/vue-app:latest
            docker stop vue-app || true
            docker rm vue-app || true
            docker run -d --name vue-app -p 80:80 your-username/vue-app:latest

Docker Compose

yaml
# docker-compose.yml
version: "3.8"

services:
  vue-app:
    image: your-username/vue-app:latest
    container_name: vue-app
    ports:
      - "80:80"
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

版本管理与回滚

镜像标签策略

bash
# 语义化版本
docker tag vue-app:latest vue-app:v1.2.3

# Git 提交哈希
docker tag vue-app:latest vue-app:abc1234

# 时间戳
docker tag vue-app:latest vue-app:20250127

回滚操作

bash
# 回滚到指定版本
docker stop vue-app
docker rm vue-app
docker run -d --name vue-app -p 80:80 your-username/vue-app:v1.2.2

# 或使用 Docker Compose
docker-compose down
docker-compose up -d --scale vue-app=0
docker-compose up -d

缓存优化策略

构建缓存优化

dockerfile
# 优化后的 Dockerfile
FROM node:18-alpine AS build

WORKDIR /app

# 先复制 package.json 利用 Docker 层缓存
COPY package*.json ./
RUN npm ci --only=production

# 再复制源代码
COPY . .
RUN npm run build

# 运行阶段
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

安全与权限配置

容器安全

dockerfile
# 使用非 root 用户
FROM nginx:alpine

# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# 切换到非 root 用户
USER nextjs

# 只读文件系统
# docker run --read-only -v /tmp:/tmp vue-app

安全扫描

yaml
# 在 CI 中添加安全扫描
- name: Run Trivy vulnerability scanner
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: "your-username/vue-app:latest"
    format: "sarif"
    output: "trivy-results.sarif"

场景四:CI/CD 流水线自动化

概述

CI/CD 流水线自动化是现代前端开发的核心,确保代码质量、构建一致性和部署可靠性。

构建过程

推荐:CI 统一构建

yaml
# 构建流程
代码提交 → 自动测试 → 自动构建 → 自动部署 → 通知结果

CI/CD 流水线设计

GitHub Actions 完整示例

yaml
name: CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  NODE_VERSION: "18"

jobs:
  # 测试阶段
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Run linting
        run: npm run lint

      - name: Run type check
        run: npm run type-check

      - name: Run tests
        run: npm run test:unit

      - name: Run e2e tests
        run: npm run test:e2e
        if: github.event_name == 'pull_request'

  # 构建阶段
  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'

    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Build application
        run: npm run build
        env:
          VITE_API_URL: ${{ secrets.API_URL }}
          VITE_APP_VERSION: ${{ github.sha }}

      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: dist
          path: dist/

  # 部署阶段
  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: production

    steps:
      - name: Download build artifacts
        uses: actions/download-artifact@v3
        with:
          name: dist
          path: dist/

      - name: Deploy to server
        uses: appleboy/ssh-action@v0.1.5
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            # 备份当前版本
            sudo cp -r /var/www/myapp /var/www/myapp.backup.$(date +%Y%m%d_%H%M%S)

            # 部署新版本
            sudo rm -rf /var/www/myapp/*
            sudo cp -r dist/* /var/www/myapp/

            # 重载服务
            sudo nginx -s reload

            # 健康检查
            curl -f http://your-domain.com || exit 1

      - name: Notify deployment
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          channel: "#deployments"
          webhook_url: ${{ secrets.SLACK_WEBHOOK }}

环境配置

yaml
# 多环境部署
jobs:
  deploy-staging:
    if: github.ref == 'refs/heads/develop'
    environment: staging
    # ... 部署到测试环境

  deploy-production:
    if: github.ref == 'refs/heads/main'
    environment: production
    # ... 部署到生产环境

版本管理与回滚

版本标记

yaml
- name: Create Git tag
  if: github.ref == 'refs/heads/main'
  run: |
    git config --local user.email "action@github.com"
    git config --local user.name "GitHub Action"
    git tag -a "v${{ github.run_number }}" -m "Release version ${{ github.run_number }}"
    git push origin "v${{ github.run_number }}"

回滚机制

yaml
# 手动回滚工作流
name: Rollback

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Version to rollback to"
        required: true
        type: string

jobs:
  rollback:
    runs-on: ubuntu-latest
    steps:
      - name: Rollback to version
        uses: appleboy/ssh-action@v0.1.5
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            # 回滚到指定版本
            sudo ln -sfn /var/www/myapp.backup.${{ github.event.inputs.version }} /var/www/myapp/current
            sudo nginx -s reload

缓存优化策略

依赖缓存

yaml
- name: Cache node modules
  uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

构建缓存

yaml
- name: Cache build
  uses: actions/cache@v3
  with:
    path: |
      node_modules/.cache
      dist
    key: ${{ runner.os }}-build-${{ hashFiles('**/package-lock.json') }}

安全与权限配置

密钥管理

yaml
# 使用 GitHub Secrets
env:
  API_KEY: ${{ secrets.API_KEY }}
  DATABASE_URL: ${{ secrets.DATABASE_URL }}

# 环境隔离
jobs:
  deploy:
    environment:
      name: production
      url: https://your-domain.com

权限控制

yaml
# 分支保护
on:
  push:
    branches: [main] # 只允许主分支部署

# 人工审批
environment: production
# 在 GitHub 环境设置中启用 Required reviewers

总结

选择建议

场景适用项目优势劣势
静态托管个人项目、小型应用简单易用、零配置定制化有限
云服务器企业应用、需要定制完全控制、成本可控运维复杂
容器化微服务、云原生环境一致、易扩展学习成本高
CI/CD所有项目自动化、质量保证初期配置复杂

最佳实践总结

  1. 构建策略:优先使用 CI 统一构建,确保环境一致性
  2. 版本管理:使用语义化版本和内容哈希,支持快速回滚
  3. 缓存优化:合理配置缓存策略,平衡性能和更新
  4. 安全配置:最小权限原则,密钥管理,安全扫描
  5. 监控告警:部署状态监控,异常及时通知
  6. 文档维护:部署流程文档化,便于团队协作

工具推荐

  • CI/CD:GitHub Actions、GitLab CI、Jenkins
  • 容器化:Docker、Kubernetes
  • 监控:Sentry、LogRocket、New Relic
  • 安全扫描:Snyk、OWASP ZAP、Trivy

通过采用这些最佳实践,可以构建稳定、高效、安全的前端部署流程,提升开发效率和用户体验。

本站总访问