Skip to content

前端工程化全景

工程化是将软件工程的方法论应用到前端开发,解决团队协作、代码质量、构建部署等问题。

工程化体系

前端工程化
├── 开发规范
│   ├── ESLint(代码检查)
│   ├── Prettier(代码格式化)
│   ├── TypeScript(类型安全)
│   └── Commitlint(提交规范)
├── 构建工具
│   ├── Vite(开发 + 构建)
│   ├── Webpack(复杂场景)
│   └── Rollup(库打包)
├── 测试体系
│   ├── Vitest(单元测试)
│   ├── Playwright(E2E 测试)
│   └── Storybook(组件测试)
├── CI/CD
│   ├── GitHub Actions
│   └── Docker 容器化
└── 监控
    ├── Sentry(错误监控)
    └── Web Vitals(性能监控)

项目初始化最佳实践

bash
# 创建 Vite + React + TypeScript 项目
npm create vite@latest my-app -- --template react-ts
cd my-app

# 安装依赖
npm install

# 代码规范工具
npm install -D eslint prettier
npm install -D @typescript-eslint/eslint-plugin @typescript-eslint/parser
npm install -D eslint-plugin-react eslint-plugin-react-hooks
npm install -D eslint-config-prettier  # 关闭与 Prettier 冲突的规则

# Git Hooks
npm install -D husky lint-staged
npx husky init

# 提交规范
npm install -D @commitlint/cli @commitlint/config-conventional

ESLint 配置

js
// eslint.config.js(ESLint v9 flat config)
import js from '@eslint/js'
import typescript from '@typescript-eslint/eslint-plugin'
import tsParser from '@typescript-eslint/parser'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'

export default [
  js.configs.recommended,
  {
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      parser: tsParser,
      parserOptions: {
        project: './tsconfig.json'
      }
    },
    plugins: {
      '@typescript-eslint': typescript,
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
    },
    rules: {
      // TypeScript
      '@typescript-eslint/no-explicit-any': 'warn',
      '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
      '@typescript-eslint/prefer-nullish-coalescing': 'error',

      // React Hooks
      'react-hooks/rules-of-hooks': 'error',
      'react-hooks/exhaustive-deps': 'warn',

      // 通用
      'no-console': ['warn', { allow: ['warn', 'error'] }],
      'prefer-const': 'error',
    }
  },
  {
    ignores: ['dist/', 'node_modules/', '*.config.js']
  }
]

Prettier 配置

json
// .prettierrc
{
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "arrowParens": "avoid",
  "endOfLine": "lf",
  "plugins": ["prettier-plugin-tailwindcss"]
}

Git Hooks(Husky + lint-staged)

bash
# .husky/pre-commit
npx lint-staged

# .husky/commit-msg
npx --no -- commitlint --edit $1
json
// package.json
{
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{css,scss,md,json}": [
      "prettier --write"
    ]
  }
}
js
// commitlint.config.js
export default {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [2, 'always', [
      'feat',    // 新功能
      'fix',     // Bug 修复
      'docs',    // 文档
      'style',   // 格式(不影响代码逻辑)
      'refactor',// 重构
      'perf',    // 性能优化
      'test',    // 测试
      'chore',   // 构建/工具变动
      'revert',  // 回滚
      'ci',      // CI 配置
    ]]
  }
}
// 提交格式:feat(scope): description
// 例如:feat(auth): add JWT refresh token

GitHub Actions CI/CD

yaml
# .github/workflows/ci.yml
name: CI

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

jobs:
  lint-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci

      - name: Lint
        run: npm run lint

      - name: Type Check
        run: npm run type-check

      - name: Test
        run: npm run test -- --run

      - name: Build
        run: npm run build

  deploy:
    needs: lint-and-test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci && npm run build

      # 部署到 Vercel / Netlify / 自有服务器
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.ORG_ID }}
          vercel-project-id: ${{ secrets.PROJECT_ID }}
          vercel-args: '--prod'

Monorepo(pnpm + Turborepo)

apps/
├── web/          ← Next.js 应用
├── mobile/       ← React Native 应用
└── docs/         ← VitePress 文档
packages/
├── ui/           ← 共享组件库
├── utils/        ← 共享工具函数
├── config/       ← 共享配置(ESLint、TS)
└── types/        ← 共享类型定义
json
// pnpm-workspace.yaml
packages:
  - 'apps/*'
  - 'packages/*'
json
// turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],  // 先构建依赖包
      "outputs": ["dist/**", ".next/**"]
    },
    "lint": { "outputs": [] },
    "test": { "outputs": [] },
    "dev": { "cache": false, "persistent": true }
  }
}
bash
# 并行构建所有包(Turborepo 自动处理依赖顺序)
turbo build

# 只构建受影响的包(增量构建)
turbo build --filter=[HEAD^1]

总结

  • 工程化的核心:规范(ESLint/Prettier)+ 自动化(Husky/CI)+ 可维护性
  • Commitlint 规范提交信息,便于生成 CHANGELOG
  • GitHub Actions 实现自动化测试和部署
  • Monorepo 适合多包项目,pnpm + Turborepo 是目前最佳组合

系统学习 Web 前端生态,深入底层架构