Skip to content

TypeScript项目的ESLint配置

Updated: at 15:30

众所周知,代码质量检查和代码风格的统一对于一个项目来说非常的重要,也有助于避免一些低级的错误。相信很多人都已经在前端项目中使用 ESLint 和 Prettier 了,但我猜大多数人不太清楚如何在 TypeScript 项目中进行配置,本文就来介绍具体的配置步骤。

该文章适用于 ESLint 8。 ESLint 9 开始默认启用的 flat config (即 eslint.config.js),配置文件发生了较大变化,且部分插件暂未提供 flat config 的配置,后续将单独撰文介绍

TOC

为 TypeScript 项目 设置 ESLint

ESLint 本身不是为了 TypeScript 设计的,但是它能通过配置 parser 来支持不同的语言,进而实现对 TypeScript 代码的检查和修复。

首先安装相关的依赖:

npm i -D @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint typescript

然后,添加在项目根目录添加.eslintrc.js,一个基本的例子如下:

module.exports = {
  extends: [
    'eslint:recommended', // eslint推荐规则
    'plugin:@typescript-eslint/recommended', // 使用推荐的规则,来自@typescript-eslint/eslint-plugin
  ],
  parser: '@typescript-eslint/parser', // 指定parser
  plugins: [
    '@typescript-eslint', // typescript插件
  ],
  rules: {
    // 此处书写需要覆盖的配置
    // 例如,"@typescript-eslint/explicit-function-return-type": "off",
  },
};

其中有些细节值得一提:

React 相关配置

对于 React 项目,可以添加相关插件,以进行对应的检查:

npm i -D eslint-plugin-react eslint-plugin-react-hooks

并添加 React 相关的配置:

module.exports = {
  // ...
  extends: [
    // ... 略
    'plugin:react/recommended', // 使用推荐的react规则
    'plugin:react/jsx-runtime', // for JSX transform from React 17
    'plugin:react-hooks/recommended', // 使用推荐的react-hook规则
  ],
};

自动解析和排序 import

首先依旧是安装相关依赖:

npm i -D eslint-plugin-import eslint-import-resolver-typescript

然后对应的配置文件改动:

module.exports = {
  // ...
  extends: [
    // ...
    'plugin:import/recommended',
    'plugin:import/typescript',
  ],
  settings: {
    'import/resolver': {
      typescript: true,
    },
  },
  rules: {
    'import/order': [
      'warn',
      {
        alphabetize: { order: 'asc', caseInsensitive: true }, // 同一组的import按字典序排列
        // 符合pattern的路径会放到指定的group中
        pathGroups: [
          {
            pattern: '~/**',
            group: 'internal',
          },
        ],
        'newlines-between': 'always', // 在分组与分组之间加入空行
      },
    ],
  },
  // ...
};

配置 Prettier

Prettier 和 ESLint 是两个独立的工具,Prettier 专注于代码格式化,而 ESLint 专注于代码质量检查 (顺便提供了一些修复)。Prettier 的格式化和 eslint --fix 都会涉及代码风格的调整,有时二者会发生冲突。目前社区中处理这个问题的工具有以下几种:

主流的实践是将 eslint-plugin-prettiereslint-config-prettier 结合使用,下面就介绍如何进行配置。

安装相关依赖:

npm i -D prettier eslint-config-prettier eslint-plugin-prettier

然后在根目录添加 Prettier 的配置文件.prettierrc.js,具体内容根据习惯调整:

/** @type {import("prettier").Options} */
module.exports = {
  semi: true,
  trailingComma: 'all',
  singleQuote: true,
  printWidth: 120,
  tabWidth: 4,
  // 格式与eslint的overrides类似
  overrides: [
    {
      files: '*.json',
      options: {
        tabWidth: 2,
      },
    },
    {
      files: ['*.html', 'legacy/**/*.js'],
      options: {
        printWidth: 240,
      },
    },
  ],
};

最后更新 ESLint 的配置即可:

module.exports = {
  // ...
  extends: [
    // ...
    'plugin:prettier/recommended', // 使用eslint-plugin-prettier推荐的配置,注意需要在最后一个
  ],
  // ...
};

extends 字段中添加的 plugin:prettier/recommendedeslint-plugin-prettier 提供的推荐配置,其中引用了 eslint-config-prettier 并设置相应的规则,这个配置相当于:

{
  "extends": ["prettier"],
  "plugins": ["prettier"],
  "rules": {
    "prettier/prettier": "error",
    "arrow-body-style": "off",
    "prefer-arrow-callback": "off"
  }
}

有时候会在网上的文章中看到,extends 字段中除了 prettier 外还有 prettier/react 之类的配置,但从 eslint-config-prettier 的 8.0.0 版本开始只需要一个 prettier 就能引入全部配置了

在 VS Code 中实现自动修复

大多数情况下,我们都期望能在保存代码的同时自动对代码进行 ESLint 检查,并修复能修复的问题,让代码符合风格和质量的规范,而不是在某次提交的时候才进行检查和处理。

首先需要在 VSCode 中安装扩展 ESLint

eslint-plugin

然后在 setting.json 中添加配置:

{
  "editor.codeActionsOnSave": {
    // For ESLint
    "source.fixAll.eslint": true
  }
}

网上的一些文章会提到设置 eslint.autoFixOnSaveeslint.validate,实际上这两个配置在 vscode-eslint 2.0.4 版本后已经废弃,只需要设置 codeActionsOnSave 即可

如果 VSCode 的 editor.formatOnSave 被设置为 true,还需要将对应语言的 formatOnSave 关闭以避免将代码格式化两次。settings.json 配置如下:

{
  "editor.formatOnSave": true,

  "[javascript]": {
    "editor.formatOnSave": false
  },
  "[javascriptreact]": {
    "editor.formatOnSave": false
  },
  "[typescript]": {
    "editor.formatOnSave": false
  },
  "[typescriptreact]": {
    "editor.formatOnSave": false
  }
}