Skip to content

Commit ff1aefb

Browse files
committed
chore: migrate to native eslint flat config
1 parent bf7fb9d commit ff1aefb

3 files changed

Lines changed: 99 additions & 64 deletions

File tree

.eslintrc.js

Lines changed: 0 additions & 11 deletions
This file was deleted.

eslint.config.mjs

Lines changed: 89 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,23 @@
1-
import { FlatCompat } from '@eslint/eslintrc';
21
import js from '@eslint/js';
3-
import tsEslintPlugin from '@typescript-eslint/eslint-plugin';
4-
import { createRequire } from 'node:module';
5-
import path from 'node:path';
6-
import { fileURLToPath } from 'node:url';
2+
import { defineConfig } from 'eslint/config';
3+
import prettier from 'eslint-config-prettier';
4+
import jest from 'eslint-plugin-jest';
5+
import react from 'eslint-plugin-react';
6+
import reactHooks from 'eslint-plugin-react-hooks';
7+
import globals from 'globals';
8+
import tseslint from 'typescript-eslint';
79

8-
const __filename = fileURLToPath(import.meta.url);
9-
const __dirname = path.dirname(__filename);
10-
const require = createRequire(import.meta.url);
11-
12-
const compat = new FlatCompat({
13-
baseDirectory: __dirname,
14-
recommendedConfig: js.configs.recommended,
15-
allConfig: js.configs.all,
16-
});
17-
18-
const supportedTsRules = new Set(
19-
Object.keys(tsEslintPlugin.rules).map(ruleName => `@typescript-eslint/${ruleName}`),
20-
);
21-
22-
function normalizeConfig(config) {
23-
const next = { ...config };
24-
25-
if (next.rules) {
26-
next.rules = Object.fromEntries(
27-
Object.entries(next.rules).filter(([ruleName]) => {
28-
if (ruleName.startsWith('@babel/')) {
29-
return false;
30-
}
31-
return !ruleName.startsWith('@typescript-eslint/') || supportedTsRules.has(ruleName);
32-
}),
33-
);
34-
}
35-
36-
return next;
37-
}
38-
39-
export default [
10+
export default defineConfig([
11+
{
12+
plugins: {
13+
'@typescript-eslint': tseslint.plugin,
14+
},
15+
},
16+
{
17+
linterOptions: {
18+
reportUnusedDisableDirectives: 'off',
19+
},
20+
},
4021
{
4122
ignores: [
4223
'node_modules/',
@@ -48,17 +29,83 @@ export default [
4829
'.dumi/',
4930
'.doc/',
5031
'.vercel/',
51-
'.eslintrc.js',
32+
'src/index.d.ts',
5233
],
5334
},
54-
...compat.config(require('./.eslintrc.js')).map(normalizeConfig),
5535
{
36+
files: ['**/*.{js,jsx,ts,tsx}'],
37+
extends: [
38+
js.configs.recommended,
39+
react.configs.flat.recommended,
40+
react.configs.flat['jsx-runtime'],
41+
prettier,
42+
],
43+
plugins: {
44+
'react-hooks': reactHooks,
45+
},
46+
languageOptions: {
47+
globals: {
48+
...globals.browser,
49+
...globals.node,
50+
},
51+
},
52+
settings: {
53+
react: {
54+
version: 'detect',
55+
},
56+
},
5657
rules: {
58+
'no-async-promise-executor': 'off',
59+
'no-empty-pattern': 'off',
60+
'no-irregular-whitespace': 'off',
61+
'no-prototype-builtins': 'off',
62+
'no-useless-escape': 'off',
63+
'no-extra-boolean-cast': 'off',
64+
'no-undef': 'off',
65+
'no-unused-vars': 'off',
66+
'react/no-find-dom-node': 'off',
67+
'react/display-name': 'off',
68+
'react/no-unknown-property': 'off',
69+
'react/prop-types': 'off',
70+
'react-hooks/exhaustive-deps': 'warn',
71+
'react-hooks/rules-of-hooks': 'error',
72+
},
73+
},
74+
{
75+
files: ['**/*.{ts,tsx}'],
76+
extends: [...tseslint.configs.recommended],
77+
rules: {
78+
'@typescript-eslint/ban-ts-comment': 'off',
5779
'@typescript-eslint/no-empty-object-type': 'off',
80+
'@typescript-eslint/no-explicit-any': 'off',
5881
'@typescript-eslint/no-unsafe-function-type': 'off',
82+
'@typescript-eslint/no-unnecessary-type-constraint': 'off',
5983
'@typescript-eslint/no-unused-vars': 'off',
60-
'@typescript-eslint/no-useless-constructor': 'off',
61-
'@typescript-eslint/consistent-indexed-object-style': 'off',
6284
},
6385
},
64-
];
86+
{
87+
files: ['src/**/*.{ts,tsx}'],
88+
languageOptions: {
89+
parserOptions: {
90+
projectService: true,
91+
tsconfigRootDir: import.meta.dirname,
92+
},
93+
},
94+
},
95+
{
96+
files: ['tests/**/*.{js,jsx,ts,tsx}', '**/*.{test,spec}.{js,jsx,ts,tsx}'],
97+
extends: [jest.configs['flat/recommended']],
98+
rules: {
99+
'jest/no-disabled-tests': 'off',
100+
'jest/no-done-callback': 'off',
101+
'jest/no-identical-title': 'off',
102+
'jest/expect-expect': 'off',
103+
'jest/no-alias-methods': 'off',
104+
'jest/no-conditional-expect': 'off',
105+
'jest/no-export': 'off',
106+
'jest/no-standalone-expect': 'off',
107+
'jest/valid-expect': 'off',
108+
'jest/valid-title': 'off',
109+
},
110+
},
111+
]);

package.json

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"@babel/runtime": "^7.29.7"
4343
},
4444
"devDependencies": {
45+
"@eslint/js": "^9.39.4",
4546
"@rc-component/father-plugin": "^2.2.0",
4647
"@rc-component/np": "^1.0.4",
4748
"@testing-library/jest-dom": "^6.9.1",
@@ -50,25 +51,23 @@
5051
"@types/node": "^26.0.1",
5152
"@types/react": "^19.2.17",
5253
"@types/react-dom": "^19.2.3",
53-
"@umijs/fabric": "^4.0.1",
5454
"dumi": "^2.4.38",
5555
"eslint": "^9.39.4",
56+
"eslint-config-prettier": "^10.1.8",
57+
"eslint-plugin-import": "^2.32.0",
58+
"eslint-plugin-jest": "^29.15.4",
59+
"eslint-plugin-jsx-a11y": "^6.10.2",
60+
"eslint-plugin-react": "^7.37.5",
61+
"eslint-plugin-react-hooks": "^7.1.1",
5662
"father": "^4.6.24",
5763
"gh-pages": "^6.1.1",
64+
"globals": "^17.7.0",
5865
"prettier": "^3.9.4",
66+
"rc-test": "^7.1.3",
5967
"react": "^19.2.7",
6068
"react-dom": "^19.2.7",
61-
"rc-test": "^7.1.3",
6269
"typescript": "^6.0.3",
63-
"@eslint/eslintrc": "^3.3.5",
64-
"@eslint/js": "^9.39.4",
65-
"@typescript-eslint/eslint-plugin": "^8.62.1",
66-
"@typescript-eslint/parser": "^8.62.1",
67-
"eslint-plugin-import": "^2.32.0",
68-
"eslint-plugin-jest": "^29.15.4",
69-
"eslint-plugin-jsx-a11y": "^6.10.2",
70-
"eslint-plugin-react": "^7.37.5",
71-
"eslint-plugin-react-hooks": "^7.1.1"
70+
"typescript-eslint": "^8.62.1"
7271
},
7372
"engines": {
7473
"node": ">=8.x"

0 commit comments

Comments
 (0)