第十五章:企业级部署方案

第十五章:企业级部署方案

15.1 部署前优化

生产构建配置

javascript 复制代码
// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    // 输出目录
    outDir: 'dist',
    
    // 静态资源目录
    assetsDir: 'assets',
    
    // 压缩选项
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true,
        pure_funcs: ['console.log']
      }
    },
    
    // 代码分割
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor': ['vue', 'vue-router', 'pinia'],
          'ui': ['element-plus', '@vueuse/core']
        }
      }
    },
    
    // 生成 sourcemap(生产环境建议 false 或 hidden)
    sourcemap: false,
    
    // chunk 大小警告
    chunkSizeWarningLimit: 1000,
    
    // 清空输出目录
    emptyOutDir: true
  }
})

环境变量配置

bash 复制代码
# .env.production
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App
VITE_SENTRY_DSN=https://xxx@sentry.io/xxx

# .env.staging
VITE_API_URL=https://staging-api.example.com

15.2 Docker 多阶段构建

Dockerfile 示例

dockerfile 复制代码
# 构建阶段
FROM node:18-alpine AS builder

WORKDIR /app

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

# 复制源码并构建
COPY . .
RUN npm run build

# 生产阶段
FROM nginx:alpine

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

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

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

nginx.conf 配置

nginx 复制代码
server {
    listen 80;
    server_name example.com;
    root /usr/share/nginx/html;
    index index.html;

    # Gzip 压缩
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript 
               application/javascript application/xml+rss 
               application/json;

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

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

    # API 代理
    location /api/ {
        proxy_pass https://api.example.com/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

构建和运行

bash 复制代码
# 构建镜像
docker build -t my-app:latest .

# 运行容器
docker run -d -p 80:80 --name my-app my-app:latest

# 推送到仓库
docker tag my-app:latest my-registry.com/my-app:latest
docker push my-registry.com/my-app:latest

15.3 CDN 部署

配置 CDN 路径

javascript 复制代码
// vite.config.js
export default defineConfig(({ mode }) => ({
  base: mode === 'production' 
    ? 'https://cdn.example.com/assets/' 
    : '/'
}))

上传到 CDN

bash 复制代码
# 使用 AWS S3
aws s3 sync dist/ s3://my-cdn-bucket/assets/ --acl public-read

# 使用阿里云 OSS
ossutil cp -r dist/ oss://my-bucket/assets/ --acl public-read

15.4 CI/CD 集成

GitHub Actions 完整工作流

yaml 复制代码
name: Deploy

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: 'npm'
      - run: npm ci
      - run: npm run test:unit
      - run: npm run test:e2e
      
  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm ci
      - run: npm run build
      - uses: actions/upload-artifact@v3
        with:
          name: dist
          path: dist/
          
  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: dist
          path: dist/
          
      - name: Deploy to Netlify
        uses: nwtgck/actions-netlify@v2
        with:
          publish-dir: './dist'
          production-branch: main
          github-token: ${{ secrets.GITHUB_TOKEN }}
          deploy-message: "Deploy from GitHub Actions"
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

GitLab CI 配置

yaml 复制代码
# .gitlab-ci.yml
stages:
  - test
  - build
  - deploy

variables:
  NODE_VERSION: 18

cache:
  paths:
    - node_modules/

test:
  stage: test
  image: node:${NODE_VERSION}
  script:
    - npm ci
    - npm run test:unit
  artifacts:
    reports:
      junit: junit.xml

build:
  stage: build
  image: node:${NODE_VERSION}
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/

deploy:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache rsync openssh-client
  script:
    - rsync -avz -e "ssh -o StrictHostKeyChecking=no" dist/ $SSH_USER@$SSH_HOST:/var/www/html/
  only:
    - main

15.5 云平台部署

Vercel 部署

json 复制代码
// vercel.json
{
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "devCommand": "npm run dev",
  "installCommand": "npm install",
  "framework": "vite",
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ]
}

Netlify 配置

toml 复制代码
# netlify.toml
[build]
  command = "npm run build"
  publish = "dist"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

[build.environment]
  NODE_VERSION = "18"

阿里云 OSS + CDN

bash 复制代码
# 安装 ossutil
wget http://gosspublic.alicdn.com/ossutil/1.7.3/ossutil64
chmod 755 ossutil64

# 配置
./ossutil64 config

# 上传
./ossutil64 cp -r dist/ oss://my-bucket/ --update --delete

# 刷新 CDN
./ossutil64 cdn-refresh --paths "https://cdn.example.com/*"

15.6 监控和告警

Sentry 集成

bash 复制代码
npm install @sentry/vue @sentry/tracing
javascript 复制代码
// src/main.js
import * as Sentry from '@sentry/vue'

Sentry.init({
  app,
  dsn: import.meta.env.VITE_SENTRY_DSN,
  environment: import.meta.env.MODE,
  tracesSampleRate: 0.1,
  integrations: [
    new Sentry.BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router)
    })
  ]
})

Web Vitals 监控

javascript 复制代码
// 上报性能指标
import { getCLS, getFID, getLCP, getFCP, getTTFB } from 'web-vitals'

function sendToAnalytics(metric) {
  // 发送到监控平台
  fetch('/api/metrics', {
    method: 'POST',
    body: JSON.stringify({
      name: metric.name,
      value: metric.value,
      rating: metric.rating
    })
  })
}

getCLS(sendToAnalytics)
getFID(sendToAnalytics)
getLCP(sendToAnalytics)
getFCP(sendToAnalytics)
getTTFB(sendToAnalytics)

15.7 回滚策略

版本化部署

bash 复制代码
# 构建时生成版本标识
echo $(git rev-parse --short HEAD) > dist/version.txt

# 部署时保留历史版本
rsync -avz dist/ /var/www/releases/$(date +%Y%m%d_%H%M%S)/
ln -snf /var/www/releases/$(date +%Y%m%d_%H%M%S) /var/www/current

快速回滚

bash 复制代码
# 切换到上一版本
cd /var/www/releases
ls -t | tail -n 2 | head -n 1 | xargs -I {} ln -snf {} /var/www/current

本章小结

企业级部署的核心要点:

  • 构建优化:压缩、代码分割、环境变量
  • Docker 容器化:多阶段构建、nginx 配置
  • CDN 加速:静态资源分发
  • CI/CD 自动化:GitHub Actions、GitLab CI
  • 监控告警:Sentry、Web Vitals
  • 版本管理和回滚:保障稳定
相关推荐
weixin_408099674 小时前
【实战教程】懒人精灵如何实现 OCR 文字识别?接口调用完整指南(附可运行示例)
java·前端·人工智能·后端·ocr·api·懒人精灵
小李子呢02114 小时前
前端八股5---组件通信
前端·javascript·vue.js
Daemon4 小时前
AI Agent系列记录(第二篇)
前端·人工智能·后端
JianZhen✓4 小时前
2026——Cursor全攻略+AI编程/前端辅助工具汇总(含问题速解)
前端·ai编程
vmiao4 小时前
【JS进阶】模拟正确处理并渲染后台数据
前端·javascript
小彭努力中4 小时前
204.Vue3 + OpenLayers:加载 GIF 文件(CSS 背景实现动画标记)
前端·css·vue·openlayers·geojson·webgis
Wect4 小时前
JS手撕:函数进阶 & 设计模式解析
前端·javascript·面试
chQHk57BN4 小时前
前端状态管理:Redux、Vuex、Pinia哪个更适合你?
前端
kyriewen114 小时前
每日知识点:this 指向之谜——是谁在 call 我?
前端·javascript·vue.js·前端框架·ecmascript·jquery·html5