0
# ESLint Configuration
1
2
@umijs/fabric provides a comprehensive ESLint configuration. Note that both `eslint` and `strictEslint` exports provide the same configuration despite their names suggesting different strictness levels.
3
4
## Import
5
6
```javascript
7
// ESLint configuration via direct require
8
const eslintConfig = require("@umijs/fabric/dist/eslint");
9
10
// Direct module imports (both eslint and strictEslint are identical)
11
const { eslint, strictEslint } = require("@umijs/fabric");
12
13
// For extending in .eslintrc.js
14
module.exports = {
15
extends: [require.resolve('@umijs/fabric/dist/eslint')],
16
};
17
```
18
19
## Configuration Objects
20
21
### ESLint Configuration
22
23
```typescript { .api }
24
/**
25
* ESLint configuration object
26
* Exported as 'eslint' and 'default' from main module
27
* Note: Same configuration is also exported as 'strictEslint'
28
*/
29
const eslint: ESLintConfig;
30
31
/**
32
* ESLint configuration object (identical to eslint)
33
* Exported as 'strictEslint' from main module
34
* Note: Despite the name, this is the same configuration as 'eslint'
35
*/
36
const strictEslint: ESLintConfig;
37
```
38
39
## Configuration Structure
40
41
```typescript { .api }
42
interface ESLintConfig {
43
extends: string[];
44
parser: string;
45
plugins: string[];
46
env: EnvironmentConfig;
47
rules: RulesConfig;
48
settings: SettingsConfig;
49
overrides: OverrideConfig[];
50
parserOptions: ParserOptionsConfig;
51
}
52
53
interface EnvironmentConfig {
54
browser: boolean;
55
node: boolean;
56
es6: boolean;
57
mocha: boolean;
58
jest: boolean;
59
jasmine: boolean;
60
}
61
62
interface SettingsConfig {
63
'import/resolver': {
64
node: {
65
extensions: string[];
66
};
67
};
68
'import/parsers': {
69
'@typescript-eslint/parser': string[];
70
};
71
'import/extensions': string[];
72
'import/external-module-folders': string[];
73
polyfills: string[];
74
react: {
75
version: string;
76
};
77
}
78
79
interface ParserOptionsConfig {
80
ecmaFeatures: {
81
jsx: boolean;
82
};
83
babelOptions: {
84
presets: string[];
85
plugins: Array<string | [string, any]>;
86
};
87
requireConfigFile: boolean;
88
project?: string;
89
}
90
91
interface OverrideConfig {
92
files: string[];
93
parser: string;
94
rules: Record<string, any>;
95
extends: string[];
96
}
97
98
type RulesConfig = Record<string, 0 | 1 | 2 | 'off' | 'warn' | 'error' | [string, any]>;
99
```
100
101
## Core Features
102
103
### Framework Support
104
105
- **React**: Comprehensive React and React Hooks rules
106
- **TypeScript**: Automatic TypeScript integration when `tsconfig.json` is detected
107
- **Jest**: Testing framework support with Jest-specific rules
108
- **Babel**: Advanced JavaScript features through Babel parser
109
110
### Parser Configuration
111
112
The configuration uses `@babel/eslint-parser` by default, with automatic switching to `@typescript-eslint/parser` for TypeScript files.
113
114
```typescript
115
// Parser options include:
116
const parserOptions = {
117
ecmaFeatures: { jsx: true },
118
babelOptions: {
119
presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'],
120
plugins: [
121
['@babel/plugin-proposal-decorators', { legacy: true }],
122
['@babel/plugin-proposal-class-properties', { loose: true }],
123
],
124
},
125
requireConfigFile: false,
126
project: './tsconfig.json', // When type-aware rules are enabled
127
};
128
```
129
130
### Plugin Integration
131
132
```typescript { .api }
133
/**
134
* ESLint plugins included in the configuration
135
*/
136
const plugins: string[] = [
137
'react',
138
'jest',
139
'unicorn',
140
'react-hooks'
141
];
142
```
143
144
### Environment Support
145
146
```typescript { .api }
147
/**
148
* Supported JavaScript environments
149
*/
150
const env: EnvironmentConfig = {
151
browser: true,
152
node: true,
153
es6: true,
154
mocha: true,
155
jest: true,
156
jasmine: true,
157
};
158
```
159
160
## TypeScript Integration
161
162
### Automatic Detection
163
164
The configuration automatically detects TypeScript projects by checking for `tsconfig.json` and adjusts rules accordingly.
165
166
```typescript { .api }
167
/**
168
* Check if current project is a TypeScript project
169
*/
170
const isTsProject: boolean;
171
172
/**
173
* Determine if project has more JavaScript files than TypeScript files
174
* Uses fast-glob to count .js/.jsx vs .ts/.tsx files in src directory
175
* @param path - Path to analyze (defaults to 'src')
176
* @returns Promise resolving to true if more JS files than TS files
177
*/
178
async function isJsMoreTs(path?: string): Promise<boolean>;
179
```
180
181
### TypeScript Overrides
182
183
When TypeScript is detected, additional configuration is applied:
184
185
```typescript { .api }
186
interface TypeScriptOverride {
187
files: ['**/*.{ts,tsx}'];
188
parser: '@typescript-eslint/parser';
189
rules: TypeScriptRulesConfig;
190
extends: ['prettier', 'plugin:@typescript-eslint/recommended'];
191
}
192
193
/**
194
* TypeScript-specific ESLint rules configuration
195
* Includes rules for type safety, consistency, and best practices
196
*/
197
interface TypeScriptRulesConfig {
198
'@typescript-eslint/array-type': 'error';
199
'@typescript-eslint/consistent-indexed-object-style': 1;
200
'@typescript-eslint/consistent-type-imports': 1;
201
'@typescript-eslint/dot-notation': 0 | 1; // Depends on DISABLE_TYPE_AWARE
202
'@typescript-eslint/method-signature-style': 'error';
203
'@typescript-eslint/no-confusing-non-null-assertion': 'error';
204
'@typescript-eslint/no-dupe-class-members': 'error';
205
'@typescript-eslint/no-empty-interface': 1;
206
'@typescript-eslint/no-explicit-any': 1;
207
'@typescript-eslint/no-unused-vars': 1;
208
'@typescript-eslint/prefer-for-of': 1;
209
'@typescript-eslint/prefer-function-type': 1;
210
// ... and many more TypeScript-specific rules
211
}
212
```
213
214
## Rule Categories
215
216
### React Rules
217
218
Key React-specific rules included:
219
220
- `react/display-name`: Disabled
221
- `react/jsx-props-no-spreading`: Disabled
222
- `react/state-in-constructor`: Disabled
223
- `react-hooks/rules-of-hooks`: Error
224
- `react-hooks/exhaustive-deps`: Warning
225
- `react/prop-types`: Disabled (for TypeScript projects)
226
227
### Code Quality Rules
228
229
- `no-param-reassign`: Error
230
- `no-prototype-builtins`: Disabled (too restrictive)
231
- `class-methods-use-this`: Disabled
232
- `unicorn/prevent-abbreviations`: Disabled
233
234
### Formatting Rules
235
236
Many formatting rules are disabled to avoid conflicts with Prettier:
237
238
- `arrow-body-style`: Disabled
239
- `object-curly-newline`: Disabled
240
- `space-before-function-paren`: Disabled
241
242
## Type-Aware Rules
243
244
Type-aware rules can be controlled via the `DISABLE_TYPE_AWARE` environment variable:
245
246
```bash
247
# Disable type-aware rules for better performance
248
DISABLE_TYPE_AWARE=1 eslint src/
249
250
# Enable type-aware rules (default)
251
eslint src/
252
```
253
254
## Usage Examples
255
256
### Basic Usage
257
258
```javascript
259
// .eslintrc.js
260
module.exports = {
261
extends: [require.resolve('@umijs/fabric/dist/eslint')],
262
rules: {
263
// Override specific rules if needed
264
'no-console': 'warn',
265
},
266
};
267
```
268
269
### With Custom Settings
270
271
```javascript
272
// .eslintrc.js
273
module.exports = {
274
extends: [require.resolve('@umijs/fabric/dist/eslint')],
275
globals: {
276
// Define global variables
277
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true,
278
page: true,
279
},
280
rules: {
281
// Custom rule overrides
282
'react/jsx-key': 'error',
283
},
284
};
285
```
286
287
### Programmatic Usage
288
289
```javascript
290
const { eslint, strictEslint } = require('@umijs/fabric');
291
292
// Use in custom ESLint configuration
293
const myConfig = {
294
...eslint,
295
rules: {
296
...eslint.rules,
297
'custom-rule': 'error',
298
},
299
};
300
```
301
302
## Import Resolver Configuration
303
304
The configuration includes sophisticated import resolution for TypeScript projects:
305
306
```typescript { .api }
307
interface ImportResolverConfig {
308
'import/resolver': {
309
node: {
310
extensions: string[]; // ['.js', '.jsx'] or ['.js', '.jsx', '.ts', '.tsx', '.d.ts']
311
};
312
};
313
'import/parsers': {
314
'@typescript-eslint/parser': ['.ts', '.tsx', '.d.ts'];
315
};
316
'import/extensions': ['.js', '.mjs', '.jsx', '.ts', '.tsx', '.d.ts'];
317
'import/external-module-folders': ['node_modules', 'node_modules/@types'];
318
}
319
```
320
321
This ensures proper module resolution for both JavaScript and TypeScript imports in mixed codebases.