Eslint 9.x版本

894 阅读4分钟

前言

刚好看到了Eslint更新到9版本,刚好可以拿来实践。 因为9版本废弃掉了很多方法和写法,有错误的地方,希望路过的大佬们提提建议。

首先官网给出了9版本之前的配置迁移,本人因为觉得麻烦,所以才想着重新配置一个,如果着急用的话可以使用官方的文档教程进行迁移。

这是传送门:eslint.nodejs.cn/docs/latest…

首先我们先了解一下其核心内容包含哪些内容:

  1. 规则 (Rules) :定义代码质量和风格的标准,帮助开发者保持一致性。
  2. 解析器 (Parser) :将代码转换为 AST,供 ESLint 分析。
  3. 插件 (Plugins) :扩展 ESLint,支持 Vue、TypeScript 等特性。
  4. 配置文件 (Configuration Files) :用于定义 ESLint 行为的文件。
  5. 环境 (Environments) :定义代码执行环境,启用相应的全局变量。
  6. 扩展配置 (Extends) :继承已有的配置,快速应用标准化规则。
  7. 处理器 (Processors) :用于处理特殊类型的文件,如 .vue 文件。
  8. Prettier 集成 (eslint-plugin-prettier) :集成 Prettier 来修复格式化问题。

具体的属性可以阅读官方文档这里不做详细介绍

以下配置仅供参考,可以根据自己项目的实际情况进行调整

步骤 1:安装依赖

首先,确保你已经安装了必要的开发依赖。你可以通过以下命令安装 ESLint、Prettier 以及相关的插件和解析器:

pnpm install --save-dev eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-prettier eslint-config-prettier vue-eslint-parser prettier eslint-define-config

这里的依赖解释如下:

  • eslint: ESLint 核心库。
  • eslint-plugin-vue: 为 Vue 文件提供 ESLint 支持。
  • @typescript-eslint/parser: 使 ESLint 能够解析 TypeScript 代码。
  • @typescript-eslint/eslint-plugin: 提供与 TypeScript 相关的 ESLint 规则。
  • eslint-plugin-prettier: 将 Prettier 集成到 ESLint 中,自动修复代码格式问题。
  • eslint-config-prettier: 禁用与 Prettier 冲突的 ESLint 规则。
  • vue-eslint-parser: 解析 Vue 文件,使 ESLint 能够检查 .vue 文件。
  • eslint-define-config:帮助在配置文件中定义和导出配置。

如有其他好用的可以自行安装

安装完成后在根目录下会有一个 image.png文件,并且官方也给出配置文件的命名。

image.png


//在其 `package.json` 文件中指定 `"type":"module"`
export default [
    {
        rules: {
            semi: "error",
            "prefer-const": "error"
        }
    }
];

// 如果你的项目在其 package.json 文件中没有指定 "type":"module",
则 eslint.config.js 必须是 CommonJS 格式,
module.exports = [
    {
        rules: {
            semi: "error",
            "prefer-const": "error"
        }
    }
];

我为了简化多种配置项的定义使用了eslint-define-config

//在其 `package.json` 文件中指定 `"type":"module"`
import { defineFlatConfig } from "eslint-define-config";
export default defineFlatConfig([
    {
      配置1
    },
    {其他配置},
    {...}
]);

通用配置

import js from "@eslint/js";
import pluginPrettier from "eslint-plugin-prettier";
import configPrettier from "eslint-config-prettier";
{
  ...js.configs.recommended,
  ignores: [  //忽略文件
  "**/.*", // 忽略所有隐藏文件 
  "dist/*", // 忽略 dist 文件夹 
  "*.d.ts", // 忽略所有类型声明文件 (.d.ts) 
  "public/*", // 忽略 public 文件夹
  .....
  ],
  languageOptions: {
    globals: {
      // 比如定义在代码中全局使用的只读变量
      // RefType: "readonly",
    },
    parserOptions: {
      // 使用最新版 ES 语法
      ecmaVersion: "latest",
      // 使用 ESLint TS 解析器
      parser: parserTypeScript,
      // 使用 ES 模块化规范
      sourceType: "module"
    }
  },
  plugins: {
    prettier: pluginPrettier // 使用 prettier 插件格式化代码
  },
  rules: {
    ...configPrettier.rules, // 启用 prettier 默认规则
    ...pluginPrettier.configs.recommended.rules, // 启用 prettier 插件推荐的规则
    "no-debugger": "off", // 禁用 debugger
    "no-unused-vars": [
      "error",
      {
        argsIgnorePattern: "^_", // 忽略参数名为 _ 的警告
        varsIgnorePattern: "^_" // 忽略变量名为 _ 的警告
      }
    ],
    "prettier/prettier": [
      "error",
      {
        endOfLine: "auto" // 自动处理换行符
      }
    ]
  }
}

TypeScript配置

{
  files: ["**/*.?([cm])ts", "**/*.?([cm])tsx"],
  languageOptions: {
    parser: parserTypeScript,
    parserOptions: {
      sourceType: "module",
      warnOnUnsupportedTypeScriptVersion: false
    }
  },
  plugins: {
    "@typescript-eslint": pluginTypeScript
  },
  rules: {
    ...pluginTypeScript.configs.strict.rules,
    "@typescript-eslint/ban-types": "off",
    "@typescript-eslint/no-redeclare": "error",
    "@typescript-eslint/ban-ts-comment": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/prefer-as-const": "warn",
    "@typescript-eslint/no-empty-function": "off",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/no-import-type-side-effects": "error",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/consistent-type-imports": [
      "error",
      { disallowTypeAnnotations: false, fixStyle: "inline-type-imports" }
    ],
    "@typescript-eslint/prefer-literal-enum-member": [
      "error",
      { allowBitwiseExpressions: true }
    ],
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        argsIgnorePattern: "^_",
        varsIgnorePattern: "^_"
      }
    ]
  }
}

JavaScript配置

{
  files: ["**/*.?([cm])js"],
  rules: {
    "@typescript-eslint/no-require-imports": "off", // 禁用 require 导入的限制
    "@typescript-eslint/no-var-requires": "off" // 禁用使用 require 的限制
  }
}

Vue配置

{
  files: ["**/*.vue"],
  languageOptions: {
    parser: parserVue,
    parserOptions: {
      ecmaFeatures: {
        jsx: true
      },
      extraFileExtensions: [".vue"],
      parser: parserTypeScript,
      sourceType: "module"
    }
  },
  plugins: {
    vue: pluginVue
  },
  processor: pluginVue.processors[".vue"],
  rules: {
    ...pluginVue.configs.base.rules,
    ...pluginVue.configs["vue3-essential"].rules,
    ...pluginVue.configs["vue3-recommended"].rules,
    "no-undef": "off",
    "no-unused-vars": "warn",
    "vue/no-v-html": "off",
    "vue/require-default-prop": "off",
    "vue/require-explicit-emits": "off",
    "vue/multi-word-component-names": "off",
    "vue/no-setup-props-reactivity-loss": "off",
    "vue/html-self-closing": [
      "error",
      {
        html: {
          void: "always",
          normal: "always",
          component: "always"
        },
        svg: "always",
        math: "always"
      }
    ]
  }
}

TypeScript 声明文件

{
  files: ["**/*.d.ts"],
  rules: {
    "eslint-comments/no-unlimited-disable": "off", // 关闭对无限制禁用 ESLint 规则的警告
    "import/no-duplicates": "off", // 禁用重复导入检查
    "unused-imports/no-unused-vars": "off" // 禁用未使用导入的警告
  }
}