Eslint 配置示例
自用的 Eslint,采用扁平配置(flatConfig),并且可以与 prettier、tsdoc 等库进行适配。
如果项目不需要在 Node.js 环境中运行,可以把 languageOptions.globals 里的 ...globals.node 去掉。
tseslint.configs.recommendedTypeChecked 意思是启用 typescript-eslint 的类型规范,这个比常规的类型检查更严格。
为了保证类型安全,可以将 eslint.config 后缀改为 .ts,在 Node.js 环境下还需要安装 jiti 开发依赖。
import js from "@eslint/js";import { defineConfig } from "eslint/config";import prettierRecommended from "eslint-plugin-prettier/recommended";import tsdoc from "eslint-plugin-tsdoc";import globals from "globals";import tseslint from "typescript-eslint";import type { Linter } from "eslint";
export default defineConfig( js.configs.recommended, tseslint.configs.recommended, // tseslint.configs.recommendedTypeChecked, prettierRecommended, { files: ["src/**/*.{js,mjs,cjs,jsx,ts,tsx,mts,cts}"], languageOptions: { ecmaVersion: 2023, globals: { ...globals.browser, ...globals.node }, parser: tseslint.parser, parserOptions: { project: "./tsconfig.json", tsconfigRootDir: import.meta.dirname, projectService: true } }, plugins: { tsdoc, "@typescript-eslint": tseslint.plugin }, rules: { "tsdoc/syntax": "warn", "prefer-const": "warn", "@typescript-eslint/no-unused-vars": [ "warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" } ], "@typescript-eslint/no-explicit-any": "warn", "@typescript-eslint/no-unsafe-assignment": "warn" } }) as Linter.Config;With Plugin Import
Section titled “With Plugin Import”import js from "@eslint/js";import { defineConfig } from "eslint/config";import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";import * as importX from "eslint-plugin-import-x";
import prettierRecommend from "eslint-plugin-prettier/recommended";import tsdoc from "eslint-plugin-tsdoc";import globals from "globals";import tseslint from "typescript-eslint";
import type { Linter } from "eslint";
export default defineConfig( js.configs.recommended, tseslint.configs.recommended, // tseslint.configs.recommendedTypeChecked, prettierRecommend, importX.flatConfigs.recommended, importX.flatConfigs.typescript, { files: ["src/**/*.{js,mjs,cjs,jsx,ts,tsx,mts,cts}"], languageOptions: { ecmaVersion: 2023, globals: { ...globals.browser, ...globals.node }, parser: tseslint.parser, parserOptions: { project: "./tsconfig.json", tsconfigRootDir: import.meta.dirname, projectService: true } }, plugins: { tsdoc, "@typescript-eslint": tseslint.plugin, "import-x": importX }, rules: { "tsdoc/syntax": "warn", "prefer-const": "warn", "@typescript-eslint/no-unused-vars": [ "warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" } ], "@typescript-eslint/no-explicit-any": "warn", "@typescript-eslint/no-unsafe-assignment": "warn", "import-x/order": [ "warn", { groups: [ "builtin", "external", "internal", "unknown", "parent", "sibling", "index", "object", "type" ], alphabetize: { order: "asc", caseInsensitive: false } } ] }, settings: { "import-x/resolver-next": [ createTypeScriptImportResolver({ // bun: true, alwaysTryTypes: true, extensions: [ ".js", ".mjs", ".jsx", ".ts", ".cts", ".mts", ".tsx", ".json" ] }) ] } }) as Linter.Config;React + Plugin Import
Section titled “React + Plugin Import”import js from "@eslint/js";import { defineConfig } from "eslint/config";import { Linter } from "eslint";import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";import importX from "eslint-plugin-import-x";
import prettierRecommend from "eslint-plugin-prettier/recommended";import * as reactHooks from "eslint-plugin-react-hooks";import reactRefresh from "eslint-plugin-react-refresh";import tsdoc from "eslint-plugin-tsdoc";import globals from "globals";import tseslint from "typescript-eslint";
export default defineConfig( js.configs.recommended, tseslint.configs.recommended, // tseslint.configs.recommendedTypeChecked, prettierRecommend, importX.flatConfigs.recommended, importX.flatConfigs.typescript, { files: ["src/**/*.{js,mjs,cjs,jsx,ts,tsx,mts,cts}"], languageOptions: { ecmaVersion: 2023, globals: { ...globals.browser }, parser: tseslint.parser, parserOptions: { project: "./tsconfig.json", tsconfigRootDir: import.meta.dirname, projectService: true } }, plugins: { tsdoc, "@typescript-eslint": tseslint.plugin, "import-x": importX, "react-hooks": reactHooks, "react-refresh": reactRefresh }, rules: { "tsdoc/syntax": "warn", "prefer-const": "warn", "@typescript-eslint/no-unused-vars": [ "warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" } ], "@typescript-eslint/no-explicit-any": "warn", "@typescript-eslint/no-unsafe-assignment": "warn", "import-x/order": [ "warn", { groups: [ "builtin", "external", "internal", "unknown", "parent", "sibling", "index", "object", "type" ], alphabetize: { order: "asc", caseInsensitive: false } } ] }, settings: { "import-x/resolver-next": [ createTypeScriptImportResolver({ // bun: true, alwaysTryTypes: true, extensions: [ ".js", ".mjs", ".jsx", ".ts", ".cts", ".mts", ".tsx", ".json" ] }) ] } }) as Linter.Config;