Skip to content
On this page

ESLint实战案例

本指南通过实际案例展示如何在不同类型的项目中配置和使用ESLint,帮助您理解在实际开发场景中如何应用ESLint。

案例1:React项目配置

项目背景

一个使用React 18和TypeScript的前端项目,需要集成ESLint来保证代码质量。

安装依赖

bash
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y

配置文件

javascript
// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    '@typescript-eslint/recommended',
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
    'plugin:jsx-a11y/recommended',
    'prettier', // 需要先安装 eslint-config-prettier
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: 'module',
    project: './tsconfig.json', // TypeScript项目需要
  },
  plugins: [
    'react',
    '@typescript-eslint',
    'react-hooks',
    'jsx-a11y',
  ],
  settings: {
    react: {
      version: 'detect', // 自动检测React版本
    },
  },
  rules: {
    'react/react-in-jsx-scope': 'off', // React 17+不需要
    'react/prop-types': 'off', // 使用TypeScript类型检查
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    'jsx-a11y/anchor-is-valid': 'off', // Next.js Link组件
  },
  overrides: [
    {
      files: ['*.test.*', '*.spec.*'],
      env: {
        jest: true,
      },
      rules: {
        'no-console': 'off',
      },
    },
  ],
};

package.json脚本

json
{
  "scripts": {
    "lint": "eslint src/ --ext .js,.jsx,.ts,.tsx",
    "lint:fix": "eslint src/ --ext .js,.jsx,.ts,.tsx --fix",
    "lint:ci": "eslint src/ --ext .js,.jsx,.ts,.tsx --format=unix --quiet"
  }
}

案例2:Node.js后端项目

项目背景

一个Express后端API项目,需要ESLint来保证服务端代码质量。

安装依赖

bash
npm install --save-dev eslint eslint-plugin-node

配置文件

javascript
// .eslintrc.js
module.exports = {
  env: {
    node: true,
    es2021: true,
    jest: true, // 包含测试环境
  },
  extends: [
    'eslint:recommended',
    'plugin:node/recommended',
  ],
  parserOptions: {
    ecmaVersion: 12,
    sourceType: 'module',
  },
  plugins: [
    'node',
  ],
  rules: {
    'node/no-unpublished-require': 'off', // 允许开发依赖
    'node/no-missing-require': 'off', // 允许动态require
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
    'no-process-exit': 'off',
    'node/handle-callback-err': 'off', // 根据项目情况调整
  },
  overrides: [
    {
      files: ['**/*.test.js', '**/*.spec.js'],
      env: {
        jest: true,
      },
      rules: {
        'node/no-unpublished-require': 'off',
        'no-console': 'off',
      },
    },
    {
      files: ['scripts/**/*.js'],
      rules: {
        'no-console': 'off', // 构建脚本可以使用console
      },
    },
  ],
};

特殊配置

javascript
// 针对不同环境的配置
module.exports = {
  // ... 其他配置
  env: {
    node: true,
    es2021: true,
    ...(process.env.NODE_ENV === 'test' && { jest: true }),
  },
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
    'no-process-exit': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
  },
};

案例3:单体仓库(Monorepo)配置

项目背景

一个包含前端React应用、后端Express API和共享工具库的单体仓库。

目录结构

monorepo/
├── .eslintrc.js          # 根配置
├── package.json
├── packages/
│   ├── frontend/
│   │   ├── .eslintrc.js  # 前端特定配置
│   │   └── src/
│   ├── backend/
│   │   ├── .eslintrc.js  # 后端特定配置
│   │   └── src/
│   └── shared/
│       ├── .eslintrc.js  # 共享库配置
│       └── src/
└── tools/
    └── eslint-config/    # 共享ESLint配置

根配置

javascript
// .eslintrc.js
module.exports = {
  root: true, // 根配置,阻止ESLint向上搜索配置
  extends: ['eslint:recommended'],
  rules: {
    'no-console': 'warn',
    'no-debugger': 'error',
  },
  overrides: [
    {
      files: ['packages/frontend/**/*'],
      extends: [
        'eslint:recommended',
        '@typescript-eslint/recommended',
        'plugin:react/recommended',
      ],
      plugins: ['react'],
      settings: {
        react: {
          version: 'detect',
        },
      },
    },
    {
      files: ['packages/backend/**/*'],
      env: {
        node: true,
      },
      extends: ['eslint:recommended', 'plugin:node/recommended'],
      plugins: ['node'],
    },
    {
      files: ['packages/shared/**/*'],
      extends: ['eslint:recommended', '@typescript-eslint/recommended'],
      plugins: ['@typescript-eslint'],
    },
  ],
};

前端配置

javascript
// packages/frontend/.eslintrc.js
module.exports = {
  extends: [
    '../../tools/eslint-config/react-base',
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
    'prettier',
  ],
  settings: {
    react: {
      version: 'detect',
    },
  },
  rules: {
    'react/react-in-jsx-scope': 'off',
    'react/prop-types': 'off',
  },
};

后端配置

javascript
// packages/backend/.eslintrc.js
module.exports = {
  extends: [
    '../../tools/eslint-config/node-base',
    'plugin:node/recommended',
  ],
  env: {
    node: true,
    es6: true,
  },
  rules: {
    'node/no-unpublished-require': 'off',
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
  },
};

案例4:Next.js项目配置

安装依赖

bash
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y @next/eslint-plugin-next

配置文件

javascript
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    '@typescript-eslint/recommended',
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
    'plugin:jsx-a11y/recommended',
    'plugin:@next/next/recommended', // Next.js特定规则
    'prettier',
  ],
  env: {
    browser: true,
    node: true,
    es6: true,
  },
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: 'module',
  },
  settings: {
    react: {
      version: 'detect',
    },
  },
  rules: {
    'react/react-in-jsx-scope': 'off',
    'react/prop-types': 'off',
    '@next/next/no-html-link-for-pages': 'off', // 如果页面结构不标准
  },
  overrides: [
    {
      files: ['next.config.js'],
      env: {
        node: true,
      },
    },
  ],
};

案例5:Vue.js项目配置

安装依赖

bash
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-vue @vue/eslint-config-typescript

配置文件

javascript
// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-essential', // 或 vue3-recommended
    '@typescript-eslint/recommended',
    'prettier',
  ],
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 12,
    sourceType: 'module',
  },
  plugins: [
    'vue',
    '@typescript-eslint',
  ],
  rules: {
    'vue/multi-word-component-names': 'off', // 根据团队偏好调整
    'vue/no-unused-vars': 'error',
  },
  overrides: [
    {
      files: ['*.vue'],
      rules: {
        'vue/script-indent': ['error', 2, { baseIndent: 1 }],
      },
    },
  ],
};

案例6:CI/CD集成

GitHub Actions工作流

yaml
# .github/workflows/eslint.yml
name: ESLint
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  eslint:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16.x, 18.x]
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # 获取完整的git历史用于比较
          
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Run ESLint on changed files
        run: |
          # 只检查变更的文件
          git diff --name-only HEAD^ HEAD --diff-filter=d | grep -E '\.(js|jsx|ts|tsx|vue)$' | xargs -r npx eslint --max-warnings 0
          
      - name: Run full ESLint
        run: npx eslint src/ --ext .js,.jsx,.ts,.tsx --max-warnings 0

生成ESLint报告

bash
# 生成JSON格式报告
npx eslint src/ --ext .js,.jsx,.ts,.tsx --format json --output-file eslint-report.json

# 生成检查报告用于CI
npx eslint src/ --ext .js,.jsx,.ts,.tsx --format unix > eslint-results.txt

案例7:自定义规则开发

创建自定义规则

javascript
// tools/eslint-plugin-custom/rules/no-direct-mutation.js
module.exports = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Disallow direct mutation of state',
      category: 'Best Practices',
      recommended: false,
    },
    fixable: null,
    schema: [], // 规则选项
  },
  create: function(context) {
    return {
      AssignmentExpression: function(node) {
        if (node.left.type === 'MemberExpression' &&
            node.left.object.name === 'state') {
          context.report({
            node: node,
            message: 'Direct mutation of state is not allowed',
          });
        }
      },
    };
  },
};

使用自定义规则

javascript
// .eslintrc.js
module.exports = {
  plugins: [
    'custom', // 引用自定义插件
  ],
  rules: {
    'custom/no-direct-mutation': 'error',
  },
};

案例8:性能优化策略

配置性能优化

javascript
// .eslintrc.js
module.exports = {
  cache: true,
  cacheLocation: 'node_modules/.cache/eslint',
  cacheStrategy: 'content',
  ignorePatterns: [
    'node_modules/',
    'dist/',
    'build/',
    '.next/',
    '.nuxt/',
    '*.min.js',
    '*.bundle.js',
  ],
  // 其他配置...
};

分批处理大项目

json
// package.json
{
  "scripts": {
    "lint:all": "eslint src/",
    "lint:components": "eslint src/components/",
    "lint:utils": "eslint src/utils/",
    "lint:api": "eslint src/api/",
    "lint:parallel": "npm-run-all --parallel lint:* --ignore-scripts"
  }
}

案例9:团队协作最佳实践

共享配置包

javascript
// packages/eslint-config-company/index.js
const restrictedImports = require('./restricted-imports');

module.exports = {
  extends: [
    'eslint:recommended',
    '@typescript-eslint/recommended',
  ],
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
    'no-restricted-imports': ['error', restrictedImports],
    'prefer-const': 'error',
    'no-var': 'error',
  },
  env: {
    browser: true,
    node: true,
    es6: true,
  },
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: 'module',
  },
};

预提交钩子

json
// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "eslint --cache --fix",
      "git add"
    ],
    "*.{js,jsx,ts,tsx,json,css,md}": [
      "prettier --write",
      "git add"
    ]
  }
}

这些实战案例展示了如何在不同类型的项目中正确配置和使用ESLint,涵盖了从简单项目到复杂单体仓库的各种场景。