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

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

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
  • 版本管理和回滚:保障稳定
相关推荐
kyriewen3 小时前
Webpack vs Vite:一个是“老黄牛”,一个是“猎豹”,你选谁?
前端·webpack·vite
打小就很皮...3 小时前
html2canvas + jsPDF 生成 PDF 的踩坑与解决方案总结
前端·pdf
全栈前端老曹3 小时前
【前端地图】多地图平台适配方案——高德、百度、腾讯、Google Maps SDK 差异对比、封装统一地图接口
前端·javascript·百度·dubbo·wgs84·gcj-02·bd09
雾岛听风6914 小时前
JavaScript基础语法速查手册
开发语言·前端·javascript
遇见~未来4 小时前
第三篇_现代布局_从弹性到网格
前端·css3
前端那点事4 小时前
Vue前端SEO优化全攻略(实操落地版,新手也能上手)
前端·vue.js
Dxy12393102164 小时前
HTML 如何使用 SVG 画曲线
前端·算法·html
用户2367829801684 小时前
从零实现 GIF 制作工具:LZW 压缩与 Median Cut 色彩量化
前端·javascript
hahaha 1hhh4 小时前
中文乱码 ubuntu autodl
linux·运维·前端
Codebee5 小时前
Harness Engineering:AICode 的灵魂
前端·人工智能·前端框架