Skip to content
第 132 / 250 章前端⏱ 10 分钟阅读

第 132 章:ESLint 与 Prettier

学习目标

  • 掌握 ESLint 在 Vue 3 + TypeScript 项目中的配置
  • 学会 Prettier 代码格式化与协作
  • 理解 ESLint 与 Prettier 的协同
  • 在 CI/CD 中集成代码规范检查

一、为什么需要代码规范

二、ESLint 基础

2.1 安装

bash
pnpm add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
pnpm add -D eslint-plugin-vue vue-eslint-parser

2.2 初始化

bash
pnpm create @eslint/config

2.3 配置文件

javascript
// .eslintrc.cjs
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
    es2022: true
  },
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 2022,
    sourceType: 'module',
    extraFileExtensions: ['.vue']
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier'
  ],
  plugins: ['@typescript-eslint', 'vue'],
  rules: {
    'vue/multi-word-component-names': 'off',
    '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
    'no-console': 'warn'
  }
};

2.4 Flat Config(ESLint 9+)

typescript
// eslint.config.js
import vue from 'eslint-plugin-vue';
import ts from '@typescript-eslint/eslint-plugin';
import vueParser from 'vue-eslint-parser';
import tsParser from '@typescript-eslint/parser';

export default [
  {
    files: ['**/*.{js,ts,vue}'],
    languageOptions: {
      parser: vueParser,
      parserOptions: {
        parser: tsParser,
        ecmaVersion: 2022,
        sourceType: 'module'
      }
    },
    plugins: { vue, '@typescript-eslint': ts },
    rules: {
      ...vue.configs['vue3-recommended'].rules,
      ...ts.configs.recommended.rules
    }
  }
];

三、Vue 规则

3.1 常用规则

javascript
rules: {
  // 必须有多个单词
  'vue/multi-word-component-names': 'error',

  // HTML 闭合
  'vue/html-self-closing': ['error', {
    html: { void: 'always', normal: 'always', component: 'always' }
  }],

  // 最大属性数
  'vue/max-attributes-per-line': ['error', { singleline: 5, multiline: 1 }],

  // 名称顺序
  'vue/order-in-components': 'error',

  // 禁止 v-html
  'vue/no-v-html': 'warn',

  // prop 类型
  'vue/require-default-prop': 'error',
  'vue/require-prop-types': 'error',

  // v-for 必须有 key
  'vue/require-v-for-key': 'error',

  // v-if 不要和 v-for 一起用
  'vue/no-use-v-if-with-v-for': 'error',

  // 不允许单独使用 v-if
  'vue/no-v-if-template-key-on-child': 'error'
}

3.2 自定义规则

javascript
// 检查组件名
'vue/component-name-in-template-casing': ['error', 'PascalCase', {
  registeredComponentsOnly: true,
  ignores: []
}]

四、TypeScript 规则

4.1 推荐配置

javascript
extends: [
  'plugin:@typescript-eslint/recommended',
  'plugin:@typescript-eslint/recommended-requiring-type-checking'
]

4.2 常用规则

javascript
rules: {
  '@typescript-eslint/no-unused-vars': 'error',
  '@typescript-eslint/no-explicit-any': 'warn',
  '@typescript-eslint/explicit-function-return-type': 'off',
  '@typescript-eslint/explicit-module-boundary-types': 'off',
  '@typescript-eslint/no-floating-promises': 'error',
  '@typescript-eslint/no-misused-promises': 'error',
  '@typescript-eslint/await-thenable': 'error'
}

4.3 类型定义

typescript
// 先定义后使用
let value: number = 0;
value = 'hello';  // ❌ 报错

五、Prettier

5.1 安装

bash
pnpm add -D prettier

5.2 配置

json
// .prettierrc.json
{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "none",
  "printWidth": 100,
  "tabWidth": 2,
  "useTabs": false,
  "arrowParens": "always",
  "endOfLine": "lf",
  "vueIndentScriptAndStyle": false
}

5.3 忽略文件

text
// .prettierignore
node_modules
dist
*.min.js

5.4 命令

json
{
  "scripts": {
    "format": "prettier --write \"src/**/*.{js,ts,vue,json,css,md}\"",
    "format:check": "prettier --check \"src/**/*.{js,ts,vue,json,css,md}\""
  }
}

六、ESLint + Prettier 协同

6.1 冲突解决

ESLint 处理:代码质量
Prettier 处理:代码格式

两者规则可能冲突,需要:

  1. 关闭 ESLint 中与格式相关的规则
  2. 启用 eslint-config-prettier

6.2 安装

bash
pnpm add -D eslint-config-prettier
javascript
// .eslintrc.cjs
extends: [
  'eslint:recommended',
  'plugin:vue/vue3-recommended',
  'plugin:@typescript-eslint/recommended',
  'prettier'  // 必须在最后
]

6.3 验证冲突

bash
# npm
npx eslint-config-prettier .eslintrc.cjs

# pnpm
pnpm dlx eslint-config-prettier .eslintrc.cjs

七、Stylelint

7.1 安装

bash
pnpm add -D stylelint stylelint-config-standard stylelint-config-recommended-vue

7.2 配置

javascript
// .stylelintrc.cjs
module.exports = {
  extends: [
    'stylelint-config-standard',
    'stylelint-config-recommended-vue'
  ],
  rules: {
    'selector-class-pattern': null,
    'no-descending-specificity': null
  }
};

7.3 命令

json
{
  "scripts": {
    "lint:style": "stylelint \"src/**/*.{css,scss,vue}\""
  }
}

八、编辑器集成

8.1 VSCode

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

8.2 推荐插件

  • ESLint
  • Prettier
  • stylelint
  • Volar
  • Vue VSCode Snippets

九、Git Hooks

9.1 Husky

bash
pnpm add -D husky
npx husky init

9.2 pre-commit

bash
# .husky/pre-commit
pnpm exec lint-staged

9.3 lint-staged

bash
pnpm add -D lint-staged
json
// package.json
{
  "lint-staged": {
    "*.{js,ts,vue}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{css,scss}": [
      "stylelint --fix",
      "prettier --write"
    ],
    "*.md": [
      "prettier --write"
    ]
  }
}

9.4 commitlint

bash
pnpm add -D @commitlint/cli @commitlint/config-conventional
javascript
// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional']
};
bash
# .husky/commit-msg
pnpm exec commitlint --edit "$1"

十、CI 集成

10.1 GitHub Actions

yaml
# .github/workflows/lint.yml
name: Lint

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm

      - run: pnpm install --frozen-lockfile
      - run: pnpm lint
      - run: pnpm format:check
      - run: pnpm type-check

10.2 类型检查

json
{
  "scripts": {
    "type-check": "vue-tsc --noEmit"
  }
}

十一、组合命令

json
{
  "scripts": {
    "lint": "eslint \"src/**/*.{js,ts,vue}\" --fix",
    "lint:check": "eslint \"src/**/*.{js,ts,vue}\"",
    "format": "prettier --write \"src/**/*.{js,ts,vue,json,css,md}\"",
    "format:check": "prettier --check \"src/**/*.{js,ts,vue,json,css,md}\"",
    "lint:style": "stylelint \"src/**/*.{css,scss,vue}\" --fix",
    "type-check": "vue-tsc --noEmit",
    "verify": "pnpm lint:check && pnpm format:check && pnpm lint:style && pnpm type-check"
  }
}

十二、规则分层

javascript
// .eslintrc.cjs
module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-recommended'
  ],
  overrides: [
    {
      files: ['*.ts'],
      extends: [
        'plugin:@typescript-eslint/recommended'
      ],
      rules: {
        '@typescript-eslint/explicit-function-return-type': 'off'
      }
    },
    {
      files: ['*.test.ts'],
      env: {
        jest: true
      }
    },
    {
      files: ['vite.config.ts'],
      env: {
        node: true
      }
    }
  ]
};

十三、常见问题

13.1 ESLint 不识别 .vue

bash
npm install --save-dev eslint-plugin-vue vue-eslint-parser
javascript
parser: 'vue-eslint-parser',
parserOptions: {
  parser: '@typescript-eslint/parser',
  extraFileExtensions: ['.vue']
}

13.2 与 Prettier 冲突

bash
pnpm add -D eslint-config-prettier
javascript
extends: [
  // ... 其他
  'prettier'  // 最后
]

13.3 旧代码豁免

javascript
// .eslintrc.cjs
{
  ignorePatterns: ['src/legacy/**', '*.min.js']
}
javascript
// 单行豁免
// eslint-disable-next-line no-console
console.log('debug');

// 整个文件
/* eslint-disable no-console */

十四、lint-staged 进阶

json
{
  "lint-staged": {
    "*.{js,ts,vue}": [
      "eslint --fix --max-warnings=0",
      "prettier --write"
    ],
    "*.{css,scss,vue}": [
      "stylelint --fix",
      "prettier --write"
    ]
  }
}

十五、本章小结

工具职责
ESLint代码质量、错误检查
Prettier代码格式化
StylelintCSS/SCSS 检查
HuskyGit hooks
lint-staged仅 lint 暂存文件
commitlint提交信息规范

动手练习

  1. 基础配置:为项目配置 ESLint + Prettier
  2. Vue 规则:为 Vue 3 启用推荐规则集
  3. Git Hooks:配置 pre-commit 时自动 lint
  4. CI 集成:在 GitHub Actions 中运行 lint
  5. 规范提交:配置 commitlint 并使用规范化提交

推荐阅读


下一章第 133 章:Vitest 单元测试

本站基于 VitePress 构建 · 由 Codebook 团队维护