欢迎光临
我们一直在努力

前端CI/CD流水线搭建:从代码提交到自动部署

前端CI/CD流水线搭建:从代码提交到自动部署

大家好,我是蔓蔓。在大厂工作时,我负责搭建了团队的CI/CD流水线,将部署时间从原来的30分钟缩短到了5分钟以内。今天我来和大家分享如何从零开始搭建一套完整的前端CI/CD流水线。

CI/CD概述

什么是CI/CD

  • CI(持续集成):频繁地将代码集成到主分支,并进行自动化测试
  • CD(持续交付/部署):自动化地将代码部署到生产环境

为什么需要CI/CD

  • 减少人工操作:自动化构建、测试、部署流程
  • 提高代码质量:每次提交都进行自动化测试
  • 快速反馈:发现问题及时修复
  • 降低部署风险:小步快跑,减少单次变更
  • 流水线架构

    整体流程

    代码提交 → 代码审查 → 自动化测试 → 构建 → 部署 → 监控

    关键组件

  • 版本控制:Git(GitHub/GitLab/GitHub)
  • CI工具:GitHub Actions、GitLab CI、Jenkins
  • 测试框架:Jest、Cypress、Playwright
  • 构建工具:Webpack、Vite、Rollup
  • 部署目标:Vercel、Netlify、云服务器、Docker
  • 环境准备

    安装必要工具

    # 安装 Node.js
    curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash –
    sudo apt-get install -y nodejs

    # 安装 npm 依赖
    npm install

    # 安装 Docker(可选)
    sudo apt-get update
    sudo apt-get install docker-ce docker-ce-cli containerd.io

    项目配置

    {
    "scripts": {
    "start": "vite",
    "build": "vite build",
    "test": "jest",
    "test:e2e": "cypress run",
    "lint": "eslint .",
    "preview": "vite preview"
    }
    }

    GitHub Actions配置

    基础配置

    name: CI/CD Pipeline

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

    jobs:
    build:
    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: Lint
    run: npm run lint

    – name: Test
    run: npm test

    – name: Build
    run: npm run build

    – name: Deploy
    uses: peaceiris/actions-gh-pages@v3
    with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    publish_dir: ./dist

    多环境部署

    jobs:
    deploy:
    runs-on: ubuntu-latest
    environment:
    name: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}

    steps:
    – uses: actions/checkout@v3

    – name: Setup Node.js
    uses: actions/setup-node@v3
    with:
    node-version: '18'

    – name: Install dependencies
    run: npm ci

    – name: Build
    run: npm run build
    env:
    NODE_ENV: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }}

    – name: Deploy to Staging
    if: github.ref != 'refs/heads/main'
    run: npm run deploy:staging

    – name: Deploy to Production
    if: github.ref == 'refs/heads/main'
    run: npm run deploy:production

    测试集成

    单元测试

    // sum.test.js
    test('adds 1 + 2 to equal 3', () => {
    expect(sum(1, 2)).toBe(3);
    });

    E2E测试

    // cypress/integration/app.spec.js
    describe('App', () => {
    it('should display the welcome message', () => {
    cy.visit('/');
    cy.contains('Welcome');
    });

    it('should login successfully', () => {
    cy.visit('/login');
    cy.get('input[name="email"]').type('test@example.com');
    cy.get('input[name="password"]').type('password');
    cy.get('button[type="submit"]').click();
    cy.contains('Dashboard');
    });
    });

    Docker部署

    Dockerfile

    # 开发环境
    FROM node:18-alpine AS development

    WORKDIR /app

    COPY package*.json ./
    RUN npm ci

    COPY . .

    CMD ["npm", "start"]

    # 生产环境
    FROM node:18-alpine AS production

    WORKDIR /app

    COPY package*.json ./
    RUN npm ci –only=production

    COPY . .

    RUN npm run build

    EXPOSE 3000

    CMD ["npm", "run", "start:prod"]

    Docker Compose

    version: '3.8'

    services:
    frontend:
    build:
    context: .
    target: production
    ports:
    – "3000:3000"
    environment:
    – NODE_ENV=production
    restart: unless-stopped

    部署策略

    蓝绿部署

    # 部署蓝环境
    docker-compose up -d –build

    # 切换流量
    nginx -s reload

    # 验证后停止绿环境
    docker-compose -f docker-compose.green.yml down

    滚动更新

    # 使用 Kubernetes 进行滚动更新
    kubectl set image deployment/frontend frontend=myapp:v2

    # 查看更新状态
    kubectl rollout status deployment/frontend

    # 回滚到上一版本
    kubectl rollout undo deployment/frontend

    监控告警

    日志收集

    // logger.js
    class Logger {
    constructor() {
    this.logEndpoint = process.env.LOG_ENDPOINT;
    }

    async log(message, level = 'info') {
    const payload = {
    timestamp: new Date().toISOString(),
    level,
    message,
    service: 'frontend'
    };

    await fetch(this.logEndpoint, {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
    });
    }

    error(message, error) {
    this.log({ message, stack: error?.stack }, 'error');
    }
    }

    export const logger = new Logger();

    性能监控

    // 性能监控
    const observer = new PerformanceObserver((entries) => {
    entries.forEach((entry) => {
    console.log(`${entry.name}: ${entry.duration}ms`);

    // 上报性能数据
    fetch('/api/metrics', {
    method: 'POST',
    body: JSON.stringify({
    name: entry.name,
    duration: entry.duration,
    timestamp: Date.now()
    })
    });
    });
    });

    observer.observe({ entryTypes: ['measure', 'navigation'] });

    安全性

    密钥管理

    # GitHub Secrets
    secrets:
    DATABASE_URL: ${{ secrets.DATABASE_URL }}
    API_KEY: ${{ secrets.API_KEY }}
    NODE_ENV: production

    安全扫描

    – name: Security Scan
    uses: snyk/actions/node@master
    env:
    SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
    with:
    args: monitor

    总结

    一个完整的CI/CD流水线应该包含以下环节:

  • 代码审查:确保代码质量
  • 自动化测试:单元测试、集成测试、E2E测试
  • 构建:生成生产环境代码
  • 部署:自动化部署到目标环境
  • 监控:实时监控应用状态
  • 技术应当有温度,一个稳定可靠的CI/CD流水线,能够让开发者更加专注于创造价值,而不是重复的操作。


    你在CI/CD方面有什么经验?欢迎在评论区交流~

    赞(0)
    未经允许不得转载:171主机测评 » 前端CI/CD流水线搭建:从代码提交到自动部署
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址