Skip to content
On this page

Prettier与ESLint集成

Prettier和ESLint是两个不同的工具,各自解决不同的问题。Prettier专注于代码格式化,而ESLint专注于代码质量问题。将它们集成在一起可以提供完整的代码质量解决方案。

为什么需要集成

Prettier vs ESLint

工具专注点主要功能
Prettier代码格式缩进、引号、分号、括号等
ESLint代码质量潜在错误、最佳实践、代码风格

集成的好处

  1. 统一代码风格 - 确保团队代码风格一致
  2. 减少配置冲突 - 避免两种工具的规则冲突
  3. 提高开发效率 - 自动格式化和质量检查
  4. 减少代码审查争论 - 格式问题自动修复

基础集成

安装依赖

bash
npm install --save-dev eslint-config-prettier eslint-plugin-prettier

配置ESLint

javascript
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',           // ESLint推荐规则
    'plugin:prettier/recommended',  // 启用prettier规则
  ],
  plugins: ['prettier'],
  rules: {
    'prettier/prettier': 'error',   // 将格式问题作为错误
  },
};

Prettier配置

json
// .prettierrc
{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "bracketSpacing": true,
  "arrowParens": "avoid"
}

高级集成配置

使用eslint-config-prettier

eslint-config-prettier会关闭所有与Prettier冲突的ESLint规则:

javascript
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'prettier',                    // 关闭与Prettier冲突的规则
    'plugin:prettier/recommended', // 启用prettier推荐配置
  ],
  plugins: ['prettier'],
  rules: {
    'prettier/prettier': [
      'error',
      {
        'singleQuote': true,
        'trailingComma': 'es5',
        'printWidth': 80,
      },
    ],
  },
};

针对不同文件类型的配置

javascript
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'prettier',
    'plugin:prettier/recommended',
  ],
  overrides: [
    {
      files: ['*.ts', '*.tsx'],
      extends: [
        '@typescript-eslint/recommended',
        'prettier', // 确保关闭与Prettier的TypeScript相关冲突规则
      ],
    },
    {
      files: ['*.vue'],
      extends: [
        'plugin:vue/vue3-essential',
        'prettier',
      ],
    },
  ],
};

框架特定集成

React项目集成

javascript
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
    'prettier',
    'plugin:prettier/recommended',
  ],
  plugins: [
    'react',
    'prettier',
  ],
  rules: {
    'prettier/prettier': 'error',
    'react/react-in-jsx-scope': 'off', // React 17+
  },
  settings: {
    react: {
      version: 'detect',
    },
  },
};

TypeScript项目集成

javascript
// .eslintrc.js
module.exports = {
  parser: '@typescript-eslint/parser',
  extends: [
    'eslint:recommended',
    '@typescript-eslint/recommended',
    'prettier',
    'plugin:prettier/recommended',
  ],
  plugins: [
    '@typescript-eslint',
    'prettier',
  ],
  rules: {
    'prettier/prettier': 'error',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
  },
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: 'module',
  },
};

Vue.js项目集成

javascript
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-essential',
    'prettier',
    'plugin:prettier/recommended',
  ],
  plugins: [
    'vue',
    'prettier',
  ],
  rules: {
    'prettier/prettier': 'error',
    'vue/html-self-closing': 'off', // 可根据团队偏好调整
  },
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 2020,
    sourceType: 'module',
  },
};

编辑器配置

VS Code配置

json
// .vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "eslint.format.enable": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.fixAll.prettier": true
  },
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact",
    "vue",
    "html",
    "json",
    "markdown"
  ]
}

统一格式化配置

json
// package.json
{
  "scripts": {
    "format": "prettier --write .",
    "lint": "eslint src/ --ext .js,.jsx,.ts,.tsx",
    "lint:fix": "eslint src/ --ext .js,.jsx,.ts,.tsx --fix"
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx,json,css,md}": [
      "prettier --write",
      "eslint --fix",
      "git add"
    ]
  }
}

CI/CD集成

GitHub Actions配置

yaml
# .github/workflows/format.yml
name: Format Check
on: [push, pull_request]

jobs:
  prettier:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '16'
      - name: Install dependencies
        run: npm ci
      - name: Run Prettier check
        run: npx prettier --check "**/*.{js,jsx,ts,tsx,json,css,md}"
  eslint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '16'
      - name: Install dependencies
        run: npm ci
      - name: Run ESLint
        run: npx eslint src/ --ext .js,.jsx,.ts,.tsx --max-warnings 0

常见问题和解决方案

1. 规则冲突

问题: ESLint和Prettier规则冲突

解决方案:

javascript
// 确保使用eslint-config-prettier
module.exports = {
  extends: [
    'eslint:recommended',
    'prettier', // 这会关闭冲突的规则
  ],
};

2. 性能问题

问题: 同时运行ESLint和Prettier导致性能下降

解决方案:

json
// package.json
{
  "scripts": {
    // 先格式化再检查
    "lint": "npm run format && eslint src/",
    "lint:fast": "eslint src/ --cache" // 使用缓存
  }
}

3. 配置复杂性

问题: 配置文件变得复杂

解决方案: 使用预设配置

javascript
// .eslintrc.js
module.exports = {
  extends: [
    '@company/eslint-config', // 使用公司共享配置
    'prettier',              // 集成Prettier
  ],
};

高级配置技巧

条件启用Prettier

javascript
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    process.env.CI ? 'prettier' : 'plugin:prettier/recommended',
  ],
  rules: {
    'prettier/prettier': process.env.CI ? 'off' : 'error',
  },
};

项目特定覆盖

javascript
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'prettier',
    'plugin:prettier/recommended',
  ],
  overrides: [
    {
      files: ['**/*.test.{js,ts}'],
      rules: {
        'prettier/prettier': 'warn', // 测试文件只警告
      },
    },
  ],
};

最佳实践

1. 统一工作流程

bash
# 推荐的工作流程
1. 代码编写
2. 保存时自动格式化 (Prettier)
3. 保存时自动修复 (ESLint)
4. 提交前全面检查

2. 团队配置

javascript
// 共享配置包
// @company/eslint-config-prettier/index.js
module.exports = {
  extends: [
    'eslint:recommended',
    'prettier',
    'plugin:prettier/recommended',
  ],
  plugins: ['prettier'],
  rules: {
    'prettier/prettier': 'error',
  },
};

3. 渐进式采用

javascript
// 逐步集成
// 阶段1: 只使用Prettier
// 阶段2: 添加ESLint基础规则
// 阶段3: 集成Prettier和ESLint
// 阶段4: 添加框架特定规则

通过正确集成Prettier和ESLint,可以建立一个强大的代码质量保证体系,既保证代码格式的一致性,又确保代码质量。