Skip to content

Commit ff2a1a6

Browse files
committed
chore: migrate to native eslint flat config
1 parent a12488f commit ff2a1a6

3 files changed

Lines changed: 87 additions & 97 deletions

File tree

.eslintrc.js

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

eslint.config.mjs

Lines changed: 84 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +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 legacyConfig = require('./.eslintrc.js');
19-
const recommendedTsRulesConfig = tsEslintPlugin.configs.recommended;
20-
const recommendedTsRulesObject = Array.isArray(recommendedTsRulesConfig)
21-
? recommendedTsRulesConfig.reduce(
22-
(rules, config) => ({ ...rules, ...(config.rules || {}) }),
23-
{},
24-
)
25-
: recommendedTsRulesConfig?.rules || {};
26-
const recommendedTsRules = new Set(Object.keys(recommendedTsRulesObject));
27-
28-
function hasCurrentTsRule(ruleName) {
29-
const tsRuleName = ruleName.replace('@typescript-eslint/', '');
30-
return Boolean(tsEslintPlugin.rules[tsRuleName]);
31-
}
32-
const localTsRules = new Set(
33-
Object.keys(legacyConfig.rules || {}).filter(
34-
(ruleName) =>
35-
ruleName.startsWith('@typescript-eslint/') && hasCurrentTsRule(ruleName),
36-
),
37-
);
38-
39-
const noopRule = {
40-
meta: { type: 'problem', docs: {}, schema: [] },
41-
create: () => ({}),
42-
};
43-
44-
function normalizeConfig(config) {
45-
const next = { ...config };
46-
47-
if (next.plugins?.['@typescript-eslint']) {
48-
next.plugins = { ...next.plugins };
49-
delete next.plugins['@typescript-eslint'];
50-
}
51-
52-
if (next.rules) {
53-
next.rules = Object.fromEntries(
54-
Object.entries(next.rules).filter(([ruleName]) => {
55-
if (ruleName.startsWith('@babel/')) {
56-
return false;
57-
}
58-
if (!ruleName.startsWith('@typescript-eslint/')) {
59-
return true;
60-
}
61-
return recommendedTsRules.has(ruleName) || localTsRules.has(ruleName);
62-
}),
63-
);
64-
}
65-
66-
return next;
67-
}
68-
69-
export default [
10+
export default defineConfig([
11+
{
12+
plugins: {
13+
'@typescript-eslint': tseslint.plugin,
14+
},
15+
},
16+
{
17+
linterOptions: {
18+
reportUnusedDisableDirectives: 'off',
19+
},
20+
},
7021
{
7122
ignores: [
7223
'node_modules/',
@@ -78,27 +29,84 @@ export default [
7829
'.dumi/',
7930
'.doc/',
8031
'.vercel/',
81-
'.eslintrc.js',
32+
'src/locale/*.js',
8233
'src/index.d.ts',
8334
],
8435
},
8536
{
37+
files: ['**/*.{js,jsx,ts,tsx}'],
38+
extends: [
39+
js.configs.recommended,
40+
react.configs.flat.recommended,
41+
react.configs.flat['jsx-runtime'],
42+
prettier,
43+
],
8644
plugins: {
87-
'@typescript-eslint': {
88-
...tsEslintPlugin,
89-
rules: {
90-
...tsEslintPlugin.rules,
91-
'consistent-type-exports': noopRule,
92-
},
45+
'react-hooks': reactHooks,
46+
},
47+
languageOptions: {
48+
globals: {
49+
...globals.browser,
50+
...globals.node,
51+
},
52+
},
53+
settings: {
54+
react: {
55+
version: 'detect',
9356
},
9457
},
58+
rules: {
59+
'no-async-promise-executor': 'off',
60+
'no-empty-pattern': 'off',
61+
'no-irregular-whitespace': 'off',
62+
'no-prototype-builtins': 'off',
63+
'no-useless-escape': 'off',
64+
'no-extra-boolean-cast': 'off',
65+
'no-undef': 'off',
66+
'no-unused-vars': 'off',
67+
'react/no-find-dom-node': 'off',
68+
'react/display-name': 'off',
69+
'react/no-unknown-property': 'off',
70+
'react/prop-types': 'off',
71+
'react-hooks/exhaustive-deps': 'warn',
72+
'react-hooks/rules-of-hooks': 'error',
73+
},
9574
},
96-
...compat.config(legacyConfig).map(normalizeConfig),
9775
{
76+
files: ['**/*.{ts,tsx}'],
77+
extends: [...tseslint.configs.recommended],
9878
rules: {
79+
'@typescript-eslint/ban-ts-comment': 'off',
9980
'@typescript-eslint/no-empty-object-type': 'off',
81+
'@typescript-eslint/no-explicit-any': 'off',
10082
'@typescript-eslint/no-unsafe-function-type': 'off',
83+
'@typescript-eslint/no-unnecessary-type-constraint': 'off',
10184
'@typescript-eslint/no-unused-vars': 'off',
10285
},
10386
},
104-
];
87+
{
88+
files: ['src/**/*.{ts,tsx}'],
89+
languageOptions: {
90+
parserOptions: {
91+
projectService: true,
92+
tsconfigRootDir: import.meta.dirname,
93+
},
94+
},
95+
},
96+
{
97+
files: ['tests/**/*.{js,jsx,ts,tsx}', '**/*.{test,spec}.{js,jsx,ts,tsx}'],
98+
extends: [jest.configs['flat/recommended']],
99+
rules: {
100+
'jest/no-disabled-tests': 'off',
101+
'jest/no-done-callback': 'off',
102+
'jest/no-identical-title': 'off',
103+
'jest/expect-expect': 'off',
104+
'jest/no-alias-methods': 'off',
105+
'jest/no-conditional-expect': 'off',
106+
'jest/no-export': 'off',
107+
'jest/no-standalone-expect': 'off',
108+
'jest/valid-expect': 'off',
109+
'jest/valid-title': 'off',
110+
},
111+
},
112+
]);

package.json

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@
7171
"clsx": "^2.1.1"
7272
},
7373
"devDependencies": {
74-
"@babel/eslint-parser": "^7.29.7",
75-
"@babel/eslint-plugin": "^7.29.7",
76-
"@eslint/eslintrc": "^3.3.5",
7774
"@eslint/js": "^9.39.4",
7875
"@rc-component/father-plugin": "^2.2.0",
7976
"@rc-component/np": "^1.0.4",
@@ -86,20 +83,17 @@
8683
"@types/node": "^26.0.1",
8784
"@types/react": "^19.2.17",
8885
"@types/react-dom": "^19.2.3",
89-
"@typescript-eslint/eslint-plugin": "^8.62.1",
90-
"@typescript-eslint/parser": "^8.62.1",
91-
"@umijs/fabric": "^4.0.1",
9286
"cross-env": "^10.1.0",
9387
"dumi": "^2.4.38",
9488
"eslint": "^9.39.4",
9589
"eslint-config-prettier": "^10.1.8",
9690
"eslint-plugin-jest": "^29.15.4",
9791
"eslint-plugin-react": "^7.37.5",
9892
"eslint-plugin-react-hooks": "^7.1.1",
99-
"eslint-plugin-unicorn": "^65.0.1",
10093
"father": "^4.6.24",
10194
"gh-pages": "^6.3.0",
10295
"glob": "^13.0.6",
96+
"globals": "^17.7.0",
10397
"husky": "^9.1.7",
10498
"identity-obj-proxy": "^3.0.0",
10599
"less": "^4.6.7",
@@ -108,7 +102,8 @@
108102
"rc-test": "^7.1.3",
109103
"react": "^19.2.7",
110104
"react-dom": "^19.2.7",
111-
"typescript": "^6.0.3"
105+
"typescript": "^6.0.3",
106+
"typescript-eslint": "^8.62.1"
112107
},
113108
"peerDependencies": {
114109
"react": ">=16.9.0",

0 commit comments

Comments
 (0)