Vue 开发者的 React 实战指南:部署与持续集成篇

作为 Vue 开发者,在迁移到 React 开发时,除了开发过程中的差异,部署和持续集成的策略也需要相应调整。本文将详细介绍 React 项目的部署流程和持续集成最佳实践。

构建流程对比

Vue 的构建流程

在 Vue 项目中,我们通常使用:

  • Vue CLI 或 Vite 构建工具
  • npm run build 生成生产环境代码
  • 输出目录通常是 dist
# Vue CLI
npm run build
# 输出到 dist 目录

# Vite
npm run build
# 输出到 dist 目录

React 的构建流程

在 React 项目中,我们主要使用:

  • Create React App (CRA) 或 Vite
  • npm run build 生成生产环境代码
  • 输出目录是 build(CRA)或 dist(Vite)
# Create React App
npm run build
# 输出到 build 目录

# Vite + React
npm run build
# 输出到 dist 目录

主要区别:

  1. 构建工具

    • Vue CLI 专注于 Vue 生态
    • CRA 专注于 React 生态
  2. 配置方式

    • Vue CLI 提供 vue.config.js
    • CRA 需要 eject 或使用 craco
  3. 输出目录

    • Vue 统一使用 dist
    • React 根据工具有所不同

环境配置

1. 环境变量

# .env
REACT_APP_API_URL=https://api.example.com
REACT_APP_ENV=production

# .env.development
REACT_APP_API_URL=http://localhost:3000
REACT_APP_ENV=development

# .env.test
REACT_APP_API_URL=http://test-api.example.com
REACT_APP_ENV=test

2. 构建配置

// craco.config.js
module.exports = {
  webpack: {
    configure: (webpackConfig) => {
      // 自定义 webpack 配置
      return webpackConfig;
    },
    plugins: [
      // 添加额外的 webpack 插件
    ]
  },
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true
      }
    }
  }
};

部署策略

1. 静态部署

# Nginx 配置
server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /api {
        proxy_pass http://api.example.com;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

2. Docker 部署

# Dockerfile
# 构建阶段
FROM node:16 as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

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

3. 容器编排

# docker-compose.yml
version: '3'
services:
  web:
    build: .
    ports:
      - "80:80"
    environment:
      - NODE_ENV=production
      - REACT_APP_API_URL=https://api.example.com
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    networks:
      - app-network

  api:
    image: api-service
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

持续集成/持续部署 (CI/CD)

1. GitHub Actions

# .github/workflows/ci.yml
name: React CI/CD

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

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Setup Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '16'

    - name: Install dependencies
      run: npm ci

    - name: Run tests
      run: npm test

    - name: Build
      run: npm run build

    - name: Deploy to production
      if: github.ref == 'refs/heads/main'
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./build

2. GitLab CI/CD

# .gitlab-ci.yml
image: node:16

stages:
  - test
  - build
  - deploy

cache:
  paths:
    - node_modules/

test:
  stage: test
  script:
    - npm ci
    - npm test

build:
  stage: build
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - build/

deploy:production:
  stage: deploy
  script:
    - apt-get update -qy
    - apt-get install -y rsync
    - rsync -avz --delete build/ user@server:/var/www/html/
  only:
    - main

性能优化

1. 代码分割

// App.js
import { lazy, Suspense } from 'react';

const Dashboard = lazy(() => import('./pages/Dashboard'));
const Profile = lazy(() => import('./pages/Profile'));

function App() {
  return (
    Loading...
}> } /> } /> ); }

2. 资源优化

// craco.config.js
const CompressionPlugin = require('compression-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  webpack: {
    plugins: [
      // Gzip 压缩
      new CompressionPlugin({
        test: /\.(js|css|html|svg)$/,
        algorithm: 'gzip'
      }),
      // 包分析
      process.env.ANALYZE && new BundleAnalyzerPlugin()
    ].filter(Boolean)
  }
};

监控与日志

1. 错误监控

// ErrorBoundary.js
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 发送错误到监控服务
    logErrorToService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return 

Something went wrong.

; } return this.props.children; } }

2. 性能监控

// performance.js
export const initPerformanceMonitoring = () => {
  // 监控页面加载性能
  window.addEventListener('load', () => {
    const timing = performance.getEntriesByType('navigation')[0];
    const metrics = {
      DNS: timing.domainLookupEnd - timing.domainLookupStart,
      TCP: timing.connectEnd - timing.connectStart,
      TTFB: timing.responseStart - timing.requestStart,
      contentLoad: timing.domContentLoadedEventEnd - timing.navigationStart,
      load: timing.loadEventEnd - timing.navigationStart
    };
    
    // 发送性能数据到监控服务
    sendMetricsToService(metrics);
  });
};

安全考虑

  1. 内容安全策略 (CSP)

    # Nginx 配置
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';";
  2. HTTPS 配置

    server {
        listen 443 ssl;
        server_name example.com;
        
        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/key.pem;
        
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        
        location / {
            root /usr/share/nginx/html;
            try_files $uri $uri/ /index.html;
        }
    }

部署检查清单

  1. 构建优化

    • 移除开发依赖
    • 优化包大小
    • 启用代码分割
    • 配置缓存策略
  2. 环境配置

    • 检查环境变量
    • 验证 API 配置
    • 确认路由配置
    • 测试代理设置
  3. 性能检查

    • 运行性能测试
    • 检查加载时间
    • 验证缓存策略
    • 确认资源优化
  4. 安全检查

    • 启用 HTTPS
    • 配置 CSP
    • 检查依赖漏洞
    • 验证认证流程

小结

  1. React 部署的特点:

    • 工具链完善
    • 配置灵活
    • 性能优先
    • 安全可靠
  2. 从 Vue 到 React 的转变:

    • 适应新的构建工具
    • 掌握部署策略
    • 理解性能优化
    • 实践安全措施
  3. 开发建议:

    • 自动化部署
    • 持续监控
    • 定期优化
    • 安全第一

至此,我们已经完成了从 Vue 到 React 的完整学习路径。希望这个系列的文章能够帮助你更好地理解和使用 React,构建出高质量的应用。

如果觉得这篇文章对你有帮助,别忘了点个赞

你可能感兴趣的:(Vue 开发者的 React 实战指南:部署与持续集成篇)