@dmitryrechkin/eslint-standard 1.4.1 โ 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -615
- package/eslint.config.mjs +47 -20
- package/package.json +27 -15
- package/src/cli/index.mjs +4 -4
- package/src/cli/setup-aggressive-cleanup.mjs +97 -0
- package/docs/AUTO_INSTALL.md +0 -50
- package/docs/COMPLEXITY_RULES.md +0 -200
package/README.md
CHANGED
|
@@ -1,686 +1,200 @@
|
|
|
1
|
-
|
|
2
1
|
# @dmitryrechkin/eslint-standard
|
|
3
2
|
|
|
4
|
-
A comprehensive ESLint configuration package with TypeScript support, featuring
|
|
5
|
-
|
|
6
|
-
## โจ Features
|
|
7
|
-
|
|
8
|
-
### **Auto-Fixing Capabilities**
|
|
9
|
-
- ๐ **Automatic Import Sorting**: Organizes imports with type imports and regular imports properly grouped
|
|
10
|
-
- ๐๏ธ **Class Member Ordering**: Auto-reorders class members by visibility (public โ protected โ private) and type (fields โ constructor โ methods)
|
|
11
|
-
- ๐ **JSDoc Alignment**: Automatically fixes JSDoc comment indentation and alignment with proper tab formatting
|
|
12
|
-
- ๐ **JSDoc Requirements**: Enforces comprehensive JSDoc documentation with auto-generation of comment blocks
|
|
13
|
-
- ๐งน **Unused Import Removal**: Automatically detects and removes unused imports
|
|
14
|
-
|
|
15
|
-
### **Code Style Enforcement**
|
|
16
|
-
- **TypeScript Support**: Full integration with `@typescript-eslint` for TypeScript-specific best practices
|
|
17
|
-
- **Modern JavaScript**: Supports ECMAScript 2020 and newer features
|
|
18
|
-
- **Consistent Formatting**: Enforces Allman brace style, tab indentation, single quotes, and semicolons
|
|
19
|
-
- **Naming Conventions**: Comprehensive naming rules for variables, functions, classes, and more
|
|
20
|
-
- **JSDoc Documentation**: Requires comprehensive documentation for all exported functions, classes, methods, interfaces, types, and enums
|
|
21
|
-
- **Code Complexity Rules**: Industry-standard complexity metrics to ensure maintainable code
|
|
22
|
-
- **Customizable**: Flexible configuration options for different project needs
|
|
3
|
+
A comprehensive ESLint configuration package with TypeScript support, featuring Prettier integration and industry-standard rules.
|
|
23
4
|
|
|
24
|
-
##
|
|
5
|
+
## ๐ Quick Start
|
|
25
6
|
|
|
26
|
-
###
|
|
7
|
+
### Installation
|
|
27
8
|
|
|
28
9
|
```bash
|
|
29
|
-
npm install @dmitryrechkin/eslint-standard
|
|
10
|
+
npm install -D @dmitryrechkin/eslint-standard
|
|
11
|
+
npx @dmitryrechkin/eslint-standard install-deps
|
|
30
12
|
```
|
|
31
13
|
|
|
32
|
-
###
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-unused-imports @stylistic/eslint-plugin eslint-plugin-jsdoc eslint-plugin-simple-import-sort eslint-plugin-perfectionist --save-dev
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Or using a single command:
|
|
39
|
-
```bash
|
|
40
|
-
npm install @dmitryrechkin/eslint-standard eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-unused-imports @stylistic/eslint-plugin eslint-plugin-jsdoc eslint-plugin-simple-import-sort eslint-plugin-perfectionist --save-dev
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## ๐ Usage
|
|
44
|
-
|
|
45
|
-
### ESLint 9+ Flat Config (Recommended)
|
|
46
|
-
|
|
47
|
-
Create an `eslint.config.mjs` file in your project root:
|
|
14
|
+
### Basic Usage
|
|
48
15
|
|
|
49
16
|
```javascript
|
|
50
|
-
|
|
17
|
+
// eslint.config.mjs
|
|
18
|
+
import config from '@dmitryrechkin/eslint-standard';
|
|
51
19
|
|
|
52
|
-
export default
|
|
53
|
-
|
|
54
|
-
files: ['**/*.{js,jsx,ts,tsx}'], // Optional: specify file patterns
|
|
55
|
-
ignores: ['dist/**', 'node_modules/**'] // Optional: additional ignore patterns
|
|
20
|
+
export default config({
|
|
21
|
+
tsconfigPath: './tsconfig.json'
|
|
56
22
|
});
|
|
57
23
|
```
|
|
58
24
|
|
|
59
|
-
|
|
25
|
+
## ๐ Available Presets
|
|
60
26
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
export default eslintStandard({
|
|
65
|
-
tsconfigPath: './tsconfig.json',
|
|
66
|
-
files: ['src/**/*.{ts,tsx}', 'tests/**/*.{ts,tsx}'],
|
|
67
|
-
ignores: ['dist/**', 'coverage/**'],
|
|
68
|
-
plugins: {
|
|
69
|
-
// Add custom plugins
|
|
70
|
-
},
|
|
71
|
-
rules: {
|
|
72
|
-
// Override or add custom rules
|
|
73
|
-
'no-console': 'warn',
|
|
74
|
-
'perfectionist/sort-classes': 'off', // Disable auto class member sorting if needed
|
|
75
|
-
// Disable JSDoc requirements if needed
|
|
76
|
-
'jsdoc/require-jsdoc': 'off',
|
|
77
|
-
'jsdoc/require-description': 'off',
|
|
78
|
-
// Disable type hint requirements (if you prefer TypeScript-only types)
|
|
79
|
-
'jsdoc/require-param-type': 'off',
|
|
80
|
-
'jsdoc/require-returns-type': 'off',
|
|
81
|
-
'jsdoc/no-types': ['error', { contexts: ['any'] }]
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Multiple Configurations
|
|
27
|
+
### Standard (Default)
|
|
28
|
+
Balanced configuration suitable for most projects.
|
|
87
29
|
|
|
88
30
|
```javascript
|
|
89
|
-
import
|
|
90
|
-
|
|
91
|
-
export default [
|
|
92
|
-
// Configuration for source files
|
|
93
|
-
eslintStandard({
|
|
94
|
-
tsconfigPath: './tsconfig.json',
|
|
95
|
-
files: ['src/**/*.{ts,tsx}']
|
|
96
|
-
}),
|
|
97
|
-
|
|
98
|
-
// Configuration for test files with different rules
|
|
99
|
-
eslintStandard({
|
|
100
|
-
tsconfigPath: './tsconfig.json',
|
|
101
|
-
files: ['tests/**/*.{ts,tsx}'],
|
|
102
|
-
rules: {
|
|
103
|
-
'no-console': 'off' // Allow console in tests
|
|
104
|
-
}
|
|
105
|
-
})
|
|
106
|
-
];
|
|
31
|
+
import config from '@dmitryrechkin/eslint-standard';
|
|
32
|
+
export default config();
|
|
107
33
|
```
|
|
108
34
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Add these scripts to your `package.json` for easy linting and formatting:
|
|
112
|
-
|
|
113
|
-
```json
|
|
114
|
-
{
|
|
115
|
-
"scripts": {
|
|
116
|
-
"lint": "eslint .",
|
|
117
|
-
"lint:fix": "eslint . --fix",
|
|
118
|
-
"format": "eslint . --fix"
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Usage Examples
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
# Check for linting errors
|
|
127
|
-
npm run lint
|
|
128
|
-
|
|
129
|
-
# Auto-fix all fixable issues (imports, member ordering, JSDoc alignment, etc.)
|
|
130
|
-
npm run lint:fix
|
|
131
|
-
|
|
132
|
-
# Same as lint:fix
|
|
133
|
-
npm run format
|
|
134
|
-
```
|
|
35
|
+
### Aggressive
|
|
36
|
+
Enhanced unused code detection for maximum code quality.
|
|
135
37
|
|
|
136
|
-
## ๐ฏ What Gets Auto-Fixed
|
|
137
|
-
|
|
138
|
-
When you run `eslint --fix`, this configuration will automatically:
|
|
139
|
-
|
|
140
|
-
1. **๐ค Sort Imports**: Organize import statements with type imports grouped correctly
|
|
141
|
-
2. **๐ Reorder Class Members**: Arrange class members by visibility and type:
|
|
142
|
-
- Static properties โ Instance properties โ Constructor โ Static methods โ Instance methods
|
|
143
|
-
- Within each group: public โ protected โ private
|
|
144
|
-
3. **๐ Fix JSDoc Comments**:
|
|
145
|
-
- Generate missing JSDoc comment blocks for functions, classes, methods, interfaces, types, and enums
|
|
146
|
-
- Align JSDoc comments with proper tab indentation
|
|
147
|
-
- Add parameter and return value placeholders
|
|
148
|
-
4. **๐งน Remove Unused Imports**: Clean up unused import statements
|
|
149
|
-
5. **โจ Format Code**: Apply consistent spacing, quotes, semicolons, and brace styles
|
|
150
|
-
|
|
151
|
-
## ๐ Code Complexity Rules
|
|
152
|
-
|
|
153
|
-
This configuration includes industry-standard complexity rules to ensure code maintainability:
|
|
154
|
-
|
|
155
|
-
### Why Complexity Matters
|
|
156
|
-
Research shows that code complexity directly correlates with:
|
|
157
|
-
- **Bug Density**: Complex code has 2-3x more bugs (McCabe, 1976)
|
|
158
|
-
- **Maintenance Cost**: 80% of software cost is maintenance (Boehm, 1987)
|
|
159
|
-
- **Developer Productivity**: Simple code is understood 5x faster (Shepperd, 1988)
|
|
160
|
-
- **Testing Difficulty**: Complex functions require exponentially more test cases
|
|
161
|
-
|
|
162
|
-
### Industry Standards & Research
|
|
163
|
-
Our pragmatic thresholds balance ideal practices with real-world needs:
|
|
164
|
-
- **McCabe Cyclomatic Complexity**: <10 is ideal, 15 is acceptable (NIST 500-235)
|
|
165
|
-
- **Function Length**: 50-100 lines is reasonable for complex business logic
|
|
166
|
-
- **Code Complete** (Steve McConnell): Maximum nesting depth of 3-4 levels
|
|
167
|
-
- **Linux Kernel Style Guide**: 3 levels of indentation maximum
|
|
168
|
-
- **Google Style Guide**: Functions that fit on one screen (roughly 50-80 lines)
|
|
169
|
-
- **Real-world experience**: Most well-maintained codebases have functions under 50 lines
|
|
170
|
-
|
|
171
|
-
### Built-in Complexity Metrics
|
|
172
|
-
All complexity rules use ESLint's built-in rules - no additional packages needed:
|
|
173
|
-
- **Cyclomatic Complexity**: Max 10 paths through a function (pragmatic balance)
|
|
174
|
-
- **Function Length**: Max 100 lines per function (realistic for complex logic)
|
|
175
|
-
- **Statement Count**: Max 20 statements per function
|
|
176
|
-
- **Nesting Depth**: Max 3 levels of block nesting
|
|
177
|
-
- **Callback Nesting**: Max 3 levels of nested callbacks
|
|
178
|
-
- **Parameters**: Max 4 parameters per function
|
|
179
|
-
- **File Length**: Warning at >300 lines per file
|
|
180
|
-
- **Line Length**: Max 120 characters (ignoring URLs and strings)
|
|
181
|
-
- **Early Returns**: Enforces guard clauses and early returns
|
|
182
|
-
- **No Nested Ternary**: Prevents complex conditional expressions
|
|
183
|
-
|
|
184
|
-
### Customizing Complexity Thresholds
|
|
185
38
|
```javascript
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
rules: {
|
|
189
|
-
// Adjust complexity limits for legacy code
|
|
190
|
-
'complexity': ['error', 15], // Allow up to 15
|
|
191
|
-
'max-lines-per-function': ['error', { max: 100 }], // Allow longer functions
|
|
192
|
-
'max-depth': ['warn', { max: 4 }], // Warn instead of error
|
|
193
|
-
// Or disable specific rules
|
|
194
|
-
'max-lines': 'off' // Disable file length check
|
|
195
|
-
}
|
|
196
|
-
});
|
|
39
|
+
import config from '@dmitryrechkin/eslint-standard/aggressive';
|
|
40
|
+
export default config();
|
|
197
41
|
```
|
|
198
42
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
- Only await actual promises (no awaiting non-thenables)
|
|
209
|
-
- No unnecessary `return await`
|
|
210
|
-
- Async functions must contain `await`
|
|
211
|
-
- No async in Promise constructor
|
|
212
|
-
|
|
213
|
-
**Array & Collection Safety**
|
|
214
|
-
- No `delete` on arrays (use splice)
|
|
215
|
-
- Array methods must return values in callbacks
|
|
216
|
-
- No duplicate imports
|
|
217
|
-
- Unique enum values
|
|
218
|
-
|
|
219
|
-
**Error Handling & Control Flow**
|
|
220
|
-
- Only throw Error objects (no string literals)
|
|
221
|
-
- No empty catch blocks
|
|
222
|
-
- No switch case fallthrough without comment
|
|
223
|
-
- No unreachable code after return/throw
|
|
224
|
-
|
|
225
|
-
**Null/Undefined Safety**
|
|
226
|
-
- Warns on always-truthy/falsy conditions
|
|
227
|
-
- Safe optional chaining usage
|
|
228
|
-
- No variable shadowing
|
|
229
|
-
- Define variables before use
|
|
230
|
-
|
|
231
|
-
**Loop & Performance Safety**
|
|
232
|
-
- Correct loop direction (prevents infinite loops)
|
|
233
|
-
- Loop conditions must be modifiable
|
|
234
|
-
- Warns on `await` in loops (performance)
|
|
235
|
-
|
|
236
|
-
**Security Basics**
|
|
237
|
-
- No `eval()` or implied eval
|
|
238
|
-
- No `new Function()`
|
|
239
|
-
- No string-based setTimeout/setInterval
|
|
240
|
-
|
|
241
|
-
**Code Clarity & Immutability**
|
|
242
|
-
- Always use curly braces (prevents bugs)
|
|
243
|
-
- Strict equality (`===` and `!==`) required
|
|
244
|
-
- `const` for unchanged variables, no `var`
|
|
245
|
-
- **Magic numbers warning** - Common values allowed (0, 1, -1, 2, 10, 100, 1000, HTTP codes, time constants)
|
|
246
|
-
- **No parameter reassignment** - Can't reassign parameters, but property mutation allowed for practical reasons
|
|
247
|
-
- Console.log warnings (only warn/error allowed)
|
|
248
|
-
- No side-effect free expressions (short-circuit `&&`/`||` allowed)
|
|
249
|
-
- Early returns encouraged
|
|
250
|
-
|
|
251
|
-
### What's NOT Included (Too Strict for Most)
|
|
252
|
-
These rules are powerful but may be too strict for some teams:
|
|
43
|
+
**Features:**
|
|
44
|
+
- โ
Enhanced unused variable detection
|
|
45
|
+
- โ
Import/export cleanup
|
|
46
|
+
- โ
Dead code detection (unreachable code)
|
|
47
|
+
- โ
Strict unused expressions rules
|
|
48
|
+
- โ
TypeScript-specific cleanup
|
|
49
|
+
|
|
50
|
+
### Library
|
|
51
|
+
Optimized for TypeScript libraries with strict API requirements.
|
|
253
52
|
|
|
254
53
|
```javascript
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
rules: {
|
|
258
|
-
// Ultra-strict type safety
|
|
259
|
-
'@typescript-eslint/strict-boolean-expressions': 'error', // No truthy/falsy
|
|
260
|
-
'@typescript-eslint/no-non-null-assertion': 'error', // No ! operator
|
|
261
|
-
|
|
262
|
-
// Extreme conventions
|
|
263
|
-
'no-implicit-coercion': 'error', // Explicit type conversions
|
|
264
|
-
'id-length': ['error', { min: 2 }], // Minimum variable name length
|
|
265
|
-
|
|
266
|
-
// Pure functional programming
|
|
267
|
-
'no-let': 'error', // Only const allowed
|
|
268
|
-
'@typescript-eslint/prefer-readonly-parameter-types': 'error', // Deep immutability
|
|
269
|
-
}
|
|
270
|
-
});
|
|
54
|
+
import config from '@dmitryrechkin/eslint-standard/library';
|
|
55
|
+
export default config();
|
|
271
56
|
```
|
|
272
57
|
|
|
273
|
-
|
|
58
|
+
**Features:**
|
|
59
|
+
- โ
Very strict unused exports detection
|
|
60
|
+
- โ
API documentation requirements (JSDoc)
|
|
61
|
+
- โ
Explicit return types
|
|
62
|
+
- โ
No console/debugging code
|
|
63
|
+
- โ
Enhanced type safety rules
|
|
274
64
|
|
|
275
|
-
|
|
65
|
+
## โ๏ธ Configuration Options
|
|
276
66
|
|
|
277
|
-
|
|
278
|
-
2. **Parameter Mutation**: Properties can be mutated (common in normalization functions)
|
|
279
|
-
3. **Short-Circuit Evaluation**: `condition && doSomething()` pattern is allowed
|
|
280
|
-
4. **Console Warnings**: Only warns to allow debugging
|
|
281
|
-
5. **Await in Loops**: Warning only - sometimes sequential is intentional
|
|
67
|
+
All configurations accept the same configuration options:
|
|
282
68
|
|
|
283
|
-
### Handling `any` Types
|
|
284
|
-
While `any` is banned by default, you can:
|
|
285
|
-
1. Use `unknown` for truly unknown types
|
|
286
|
-
2. Use proper type assertions
|
|
287
|
-
3. Temporarily disable for migration:
|
|
288
69
|
```javascript
|
|
289
|
-
|
|
290
|
-
|
|
70
|
+
export default config({
|
|
71
|
+
tsconfigPath: './tsconfig.json', // Path to TypeScript config
|
|
72
|
+
ignores: ['build/**', 'dist/**'], // Additional ignore patterns
|
|
73
|
+
files: ['src/**/*'], // File patterns to lint
|
|
74
|
+
rules: { // Rule overrides
|
|
75
|
+
'no-console': 'warn'
|
|
76
|
+
}
|
|
77
|
+
});
|
|
291
78
|
```
|
|
292
79
|
|
|
293
|
-
##
|
|
294
|
-
|
|
295
|
-
### How We Compare to Popular Configurations
|
|
296
|
-
|
|
297
|
-
This configuration is **more comprehensive and stricter** than industry standards while maintaining practical flexibility:
|
|
298
|
-
|
|
299
|
-
| Configuration | Immutability | Complexity | Security | TypeScript | Assessment |
|
|
300
|
-
|---------------|-------------|------------|----------|------------|------------|
|
|
301
|
-
| **Airbnb** | Basic (`prefer-const`, `no-param-reassign`) | None | Basic | Limited | โ
Most popular |
|
|
302
|
-
| **Google** | Basic (`prefer-const`) | None | Basic | Limited | โ
Clean & simple |
|
|
303
|
-
| **Standard** | Basic (`prefer-const`) | None | Basic | Limited | โ
Zero config |
|
|
304
|
-
| **This Config** | **Pragmatic immutability guidance** | **10+ complexity metrics** | **12+ security rules** | **25+ TS-specific rules** | ๐ข **Enterprise-grade** |
|
|
80
|
+
## ๐ ๏ธ CLI Commands
|
|
305
81
|
|
|
306
|
-
|
|
82
|
+
The package includes a CLI for dependency management:
|
|
307
83
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
- **Advantage**: Encourages immutability without dogmatic restrictions that break real-world patterns
|
|
312
|
-
|
|
313
|
-
#### **Code Complexity Management**
|
|
314
|
-
- **Industry Standard**: Usually no complexity rules (default: 20 cyclomatic complexity)
|
|
315
|
-
- **This Config**: Comprehensive complexity metrics (cyclomatic: 10, cognitive: 15, max-lines: 100)
|
|
316
|
-
- **Advantage**: Catches maintainability issues before they become technical debt
|
|
317
|
-
|
|
318
|
-
#### **Security & Safety**
|
|
319
|
-
- **Industry Standard**: Basic or no security rules
|
|
320
|
-
- **This Config**: 12+ security rules + 25+ TypeScript safety rules
|
|
321
|
-
- **Advantage**: Enterprise-level security scanning built-in
|
|
322
|
-
|
|
323
|
-
#### **TypeScript Integration**
|
|
324
|
-
- **Industry Standard**: Basic TypeScript support
|
|
325
|
-
- **This Config**: Comprehensive TypeScript-specific safety and style rules
|
|
326
|
-
- **Advantage**: Leverages TypeScript's full potential for bug prevention
|
|
327
|
-
|
|
328
|
-
### **๐ Practical Impact vs Industry Standards**
|
|
329
|
-
|
|
330
|
-
| Metric | Airbnb/Standard | This Configuration | Improvement |
|
|
331
|
-
|--------|-----------------|-------------------|-------------|
|
|
332
|
-
| **Bug Prevention** | ~60-70% | **~95%** | **+35% fewer bugs** |
|
|
333
|
-
| **Security Coverage** | ~20% | **~90%** | **+70% security coverage** |
|
|
334
|
-
| **Maintainability** | No metrics | **Comprehensive** | **Prevents technical debt** |
|
|
335
|
-
| **Type Safety** | Basic | **Advanced** | **Prevents runtime errors** |
|
|
84
|
+
```bash
|
|
85
|
+
# Install all peer dependencies
|
|
86
|
+
npx @dmitryrechkin/eslint-standard install-deps
|
|
336
87
|
|
|
337
|
-
|
|
88
|
+
# Check if dependencies are installed
|
|
89
|
+
npx @dmitryrechkin/eslint-standard check-deps
|
|
338
90
|
|
|
91
|
+
# Auto-install missing dependencies
|
|
92
|
+
npx @dmitryrechkin/eslint-standard check-deps --install
|
|
339
93
|
```
|
|
340
|
-
Basic Standard Airbnb This Config Ultra-Strict
|
|
341
|
-
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
342
|
-
โโ Google โโ Most โโ You're here โโ Impractical
|
|
343
|
-
Standard teams (dogmatic)
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
**Verdict**: This configuration provides **enterprise-grade code quality** while remaining **practically usable** - significantly more comprehensive than industry standards.
|
|
347
|
-
|
|
348
|
-
## โ ๏ธ Warning vs Error Philosophy
|
|
349
|
-
|
|
350
|
-
### **The Problem with Warnings Nobody Fixes**
|
|
351
|
-
|
|
352
|
-
> *"If we can pass then should not even display anything because nobody is going to get back to fix it"*
|
|
353
|
-
|
|
354
|
-
This configuration takes a **practical approach** to warning vs error severity:
|
|
355
|
-
|
|
356
|
-
### **๐ด Rules Set to ERROR (Build Breaking)**
|
|
357
|
-
These **must be fixed** before deployment - they represent serious bugs or security issues:
|
|
358
|
-
|
|
359
|
-
**Type & Promise Safety**
|
|
360
|
-
- `@typescript-eslint/no-explicit-any` - No `any` types (use `unknown`)
|
|
361
|
-
- `@typescript-eslint/no-floating-promises` - Must await or handle promises
|
|
362
|
-
- `@typescript-eslint/no-misused-promises` - Correct promise usage
|
|
363
|
-
- `@typescript-eslint/only-throw-error` - Only throw Error objects
|
|
364
|
-
|
|
365
|
-
**Security & Safety**
|
|
366
|
-
- `no-eval`, `no-implied-eval` - No eval usage
|
|
367
|
-
- `security/detect-pseudoRandomBytes` - Cryptographically secure random
|
|
368
|
-
- `security/detect-unsafe-regex` - Prevent ReDoS attacks
|
|
369
|
-
- `no-secrets/no-secrets` - Block secrets in code
|
|
370
|
-
|
|
371
|
-
**Code Quality**
|
|
372
|
-
- `complexity: 10` - Hard limit on function complexity
|
|
373
|
-
- `max-params: 4` - Maximum 4 parameters per function
|
|
374
|
-
- `sonarjs/cognitive-complexity: 15` - Cognitive complexity limit
|
|
375
|
-
|
|
376
|
-
### **โ ๏ธ Rules Set to WARN (Guidance Only)**
|
|
377
|
-
These provide **guidance** but don't break builds - developers **should** address them but **can** proceed:
|
|
378
|
-
|
|
379
|
-
**Code Improvement**
|
|
380
|
-
- `no-magic-numbers` - Named constants preferred (but exceptions allowed)
|
|
381
|
-
- `id-length` - Descriptive names encouraged
|
|
382
|
-
- `@typescript-eslint/naming-convention` - Consistent naming
|
|
383
94
|
|
|
384
|
-
|
|
385
|
-
- `no-await-in-loop` - Usually better alternatives exist
|
|
386
|
-
- `promise/prefer-await-to-then` - Modern async/await preferred
|
|
387
|
-
- `unicorn/no-array-reduce` - Often clearer alternatives exist
|
|
95
|
+
## ๐ฏ Rule Categories
|
|
388
96
|
|
|
389
|
-
|
|
390
|
-
-
|
|
391
|
-
-
|
|
97
|
+
### Code Quality & Safety
|
|
98
|
+
- **Type Safety**: Strict TypeScript rules, ban `any` type
|
|
99
|
+
- **Error Prevention**: Catch common bugs and unsafe patterns
|
|
100
|
+
- **Security**: Prevent common security vulnerabilities
|
|
101
|
+
- **Performance**: Avoid performance anti-patterns
|
|
392
102
|
|
|
393
|
-
|
|
394
|
-
-
|
|
103
|
+
### Code Style & Formatting
|
|
104
|
+
- **Brace Style**: Allman style (braces on new lines) via Prettier
|
|
105
|
+
- **Indentation**: Tabs with consistent spacing
|
|
106
|
+
- **Import Organization**: Automatic import sorting and grouping
|
|
107
|
+
- **JSDoc**: Required documentation with proper formatting
|
|
395
108
|
|
|
396
|
-
###
|
|
109
|
+
### Modern JavaScript/TypeScript
|
|
110
|
+
- **ES2020+ Features**: Prefer modern syntax and APIs
|
|
111
|
+
- **Functional Programming**: Pragmatic immutability patterns
|
|
112
|
+
- **Promise Handling**: Proper async/await usage
|
|
113
|
+
- **Import/Export**: Clean module system usage
|
|
397
114
|
|
|
398
|
-
|
|
399
|
-
- `functional/no-let` โ **DISABLED** (replaced with smarter `prefer-const` rule)
|
|
400
|
-
- `functional/prefer-readonly-type` โ Keep as `warn` (immutability guidance for interfaces)
|
|
401
|
-
- `functional/immutable-data` โ **DISABLED** (incompatible with common JS/TS patterns)
|
|
115
|
+
## ๐ Preset Comparison
|
|
402
116
|
|
|
403
|
-
|
|
117
|
+
| Feature | Standard | Aggressive | Library |
|
|
118
|
+
|---------|----------|------------|---------|
|
|
119
|
+
| Unused imports cleanup | โ
| โ
| โ
|
|
|
120
|
+
| Unused variables detection | Basic | Enhanced | Enhanced |
|
|
121
|
+
| Dead code detection | Basic | โ
| โ
|
|
|
122
|
+
| Unused exports check | โ | โ
| Very Strict |
|
|
123
|
+
| JSDoc requirements | Basic | Basic | Strict |
|
|
124
|
+
| Console statements | Warning | Warning | Error |
|
|
125
|
+
| Return type hints | Error | Error | Explicit |
|
|
126
|
+
| Type safety | High | High | Very High |
|
|
404
127
|
|
|
405
|
-
|
|
406
|
-
This rule is fundamentally incompatible with common, legitimate JavaScript/TypeScript patterns:
|
|
128
|
+
## ๐ง External Tools Integration
|
|
407
129
|
|
|
408
|
-
|
|
409
|
-
// โ Rule would complain about these common patterns:
|
|
410
|
-
const result = {};
|
|
411
|
-
result.user = await findUser(); // Builder pattern
|
|
412
|
-
result.customer = await findCustomer(); // Gradual construction
|
|
413
|
-
|
|
414
|
-
const config = {};
|
|
415
|
-
config.apiUrl = process.env.API_URL; // Configuration building
|
|
416
|
-
config.timeout = 5000; // Property assignment
|
|
417
|
-
|
|
418
|
-
const data = [];
|
|
419
|
-
data.push(item); // Array building
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
**๐ Why `functional/no-let` is Replaced:**
|
|
423
|
-
|
|
424
|
-
The `functional/no-let` rule produces **misleading warnings** because it can't understand control flow:
|
|
425
|
-
|
|
426
|
-
```typescript
|
|
427
|
-
// โ functional/no-let incorrectly warns about these:
|
|
428
|
-
let events = []; // But gets reassigned in try-catch!
|
|
429
|
-
let claimId = undefined; // But gets reassigned conditionally!
|
|
430
|
-
|
|
431
|
-
// โ
Built-in prefer-const is much smarter:
|
|
432
|
-
let count = 0; // No warning - gets incremented
|
|
433
|
-
const name = 'x'; // Would warn if you used 'let' here
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
**Alternative**: Use ESLint's built-in `prefer-const` rule - it's **smarter** and produces **fewer false positives**.
|
|
437
|
-
|
|
438
|
-
### **๐๏ธ Build vs Development Experience**
|
|
130
|
+
For comprehensive unused code detection, consider these additional tools:
|
|
439
131
|
|
|
440
132
|
```bash
|
|
441
|
-
#
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
# โ ๏ธ SHOWS WARNINGS - Full guidance
|
|
445
|
-
npm run lint:dev # (if you want to see all warnings)
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
**Result**: Builds only fail for **serious issues** that **must** be fixed, while warnings provide **improvement guidance** without blocking development.
|
|
133
|
+
# Find unused exports
|
|
134
|
+
npx ts-prune
|
|
449
135
|
|
|
450
|
-
|
|
136
|
+
# Find unused files
|
|
137
|
+
npx unimported
|
|
451
138
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
- **100%** of promise-related errors
|
|
455
|
-
- **100%** of null/undefined access errors
|
|
456
|
-
- **90%** of infinite loop bugs
|
|
457
|
-
- **100%** of precision loss bugs
|
|
458
|
-
- **100%** of security issues from eval/Function
|
|
139
|
+
# Advanced dead code analysis
|
|
140
|
+
npx knip
|
|
459
141
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
## ๐ Code Style Overview
|
|
463
|
-
|
|
464
|
-
### ๐ง Formatting Rules
|
|
465
|
-
|
|
466
|
-
- **Brace Style**: Allman style (braces on new lines)
|
|
467
|
-
- **Indentation**: Tabs (configurable tab width)
|
|
468
|
-
- **Quotes**: Single quotes for strings
|
|
469
|
-
- **Semicolons**: Required at statement ends
|
|
470
|
-
- **Trailing Spaces**: Automatically removed
|
|
471
|
-
|
|
472
|
-
### ๐ Before and After Examples
|
|
473
|
-
|
|
474
|
-
#### Import Sorting
|
|
475
|
-
```typescript
|
|
476
|
-
// โ Before
|
|
477
|
-
import { TypeResponse } from '../types';
|
|
478
|
-
import type { SomeInterface } from './interfaces';
|
|
479
|
-
import { EnumErrorCode } from '../enums';
|
|
480
|
-
import type { BaseConfig } from '../config';
|
|
481
|
-
|
|
482
|
-
// โ
After (auto-fixed)
|
|
483
|
-
import type { BaseConfig } from '../config';
|
|
484
|
-
import type { SomeInterface } from './interfaces';
|
|
485
|
-
import { EnumErrorCode } from '../enums';
|
|
486
|
-
import { TypeResponse } from '../types';
|
|
142
|
+
# Find unused dependencies
|
|
143
|
+
npx depcheck
|
|
487
144
|
```
|
|
488
145
|
|
|
489
|
-
|
|
490
|
-
```typescript
|
|
491
|
-
// โ Before
|
|
492
|
-
export class UserService
|
|
493
|
-
{
|
|
494
|
-
private isInitialized = false;
|
|
495
|
-
public static VERSION = '1.0.0';
|
|
496
|
-
public name: string;
|
|
497
|
-
|
|
498
|
-
private validateUser() { /* ... */ }
|
|
499
|
-
public async getUser() { /* ... */ }
|
|
500
|
-
public static getInstance() { /* ... */ }
|
|
501
|
-
constructor(name: string) { /* ... */ }
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// โ
After (auto-fixed)
|
|
505
|
-
export class UserService
|
|
506
|
-
{
|
|
507
|
-
public static VERSION = '1.0.0';
|
|
508
|
-
|
|
509
|
-
public name: string;
|
|
510
|
-
private isInitialized = false;
|
|
511
|
-
|
|
512
|
-
constructor(name: string) { /* ... */ }
|
|
513
|
-
|
|
514
|
-
public static getInstance() { /* ... */ }
|
|
515
|
-
|
|
516
|
-
public async getUser() { /* ... */ }
|
|
517
|
-
|
|
518
|
-
private validateUser() { /* ... */ }
|
|
519
|
-
}
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
#### JSDoc Documentation with Type Hints
|
|
523
|
-
```typescript
|
|
524
|
-
// โ Before - Missing JSDoc
|
|
525
|
-
export function processUser(userData: UserData): ProcessedResult {
|
|
526
|
-
return process(userData);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// โ ๏ธ After (auto-fixed) - JSDoc block generated but missing type hints
|
|
530
|
-
/**
|
|
531
|
-
*
|
|
532
|
-
* @param userData
|
|
533
|
-
* @returns
|
|
534
|
-
*/
|
|
535
|
-
export function processUser(userData: UserData): ProcessedResult {
|
|
536
|
-
return process(userData);
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
// โ Still fails - Missing type hints and descriptions
|
|
540
|
-
// ESLint errors:
|
|
541
|
-
// - Missing JSDoc @param "userData" type
|
|
542
|
-
// - Missing JSDoc @param "userData" description
|
|
543
|
-
// - Missing JSDoc @returns type
|
|
544
|
-
// - Missing JSDoc block description
|
|
545
|
-
|
|
546
|
-
// โ
Complete JSDoc with type hints (must be added manually)
|
|
547
|
-
/**
|
|
548
|
-
* Processes user data and returns formatted result.
|
|
549
|
-
* @param {UserData} userData - The user data to process
|
|
550
|
-
* @returns {ProcessedResult} The processed user result
|
|
551
|
-
*/
|
|
552
|
-
export function processUser(userData: UserData): ProcessedResult {
|
|
553
|
-
return process(userData);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// โ ๏ธ Note: ESLint cannot auto-generate type hints from TypeScript types.
|
|
557
|
-
// Type annotations must be added manually to satisfy the linter requirements.
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
#### JSDoc Alignment
|
|
561
|
-
```typescript
|
|
562
|
-
// โ Before
|
|
563
|
-
/**
|
|
564
|
-
* Process user data
|
|
565
|
-
* @param userData - The user data
|
|
566
|
-
* @returns Processed result
|
|
567
|
-
*/
|
|
568
|
-
|
|
569
|
-
// โ
After (auto-fixed)
|
|
570
|
-
/**
|
|
571
|
-
* Process user data
|
|
572
|
-
* @param userData - The user data
|
|
573
|
-
* @returns Processed result
|
|
574
|
-
*/
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
### ๐ท๏ธ Naming Conventions
|
|
578
|
-
|
|
579
|
-
- **Variables & Functions**: `camelCase`
|
|
580
|
-
- **Classes & Interfaces**: `PascalCase`
|
|
581
|
-
- **Constants**: `UPPER_CASE` or `camelCase`
|
|
582
|
-
- **Enum Members**: `UPPER_CASE` or `PascalCase`
|
|
583
|
-
- **Type Parameters**: `PascalCase`
|
|
146
|
+
## ๐ฆ Usage Recommendations
|
|
584
147
|
|
|
585
|
-
###
|
|
148
|
+
### For Applications
|
|
149
|
+
Use **Standard** preset - provides good balance of strictness and practicality.
|
|
586
150
|
|
|
587
|
-
|
|
151
|
+
### For Libraries
|
|
152
|
+
Use **Library** preset - ensures clean public APIs and comprehensive documentation.
|
|
588
153
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
- **Auto-generation Limited**: ESLint can generate JSDoc blocks but cannot infer TypeScript types
|
|
592
|
-
- **Manual Completion Needed**: Type hints must be added manually after auto-generation
|
|
154
|
+
### For Maximum Code Quality
|
|
155
|
+
Use **Aggressive** preset - comprehensive unused code detection.
|
|
593
156
|
|
|
594
|
-
|
|
157
|
+
## ๐ Example Projects
|
|
595
158
|
|
|
159
|
+
### React Application
|
|
596
160
|
```javascript
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
* @param {string} name - Parameter description is required
|
|
600
|
-
* @param {number} age - Type hint {number} is required
|
|
601
|
-
* @returns {string} Return type and description required
|
|
602
|
-
*/
|
|
603
|
-
function greet(name: string, age: number): string {
|
|
604
|
-
return `Hello ${name}, you are ${age} years old`;
|
|
605
|
-
}
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
#### Common Type Hint Patterns
|
|
161
|
+
// eslint.config.mjs
|
|
162
|
+
import config from '@dmitryrechkin/eslint-standard';
|
|
609
163
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
@param {boolean} isActive
|
|
615
|
-
@param {Object} config
|
|
616
|
-
@param {Array<string>} items
|
|
617
|
-
@param {Function} callback
|
|
618
|
-
|
|
619
|
-
// Complex types
|
|
620
|
-
@param {UserData} userData - Custom type
|
|
621
|
-
@param {Promise<Response>} response - Generic type
|
|
622
|
-
@param {string|number} id - Union type
|
|
623
|
-
@param {{name: string, age: number}} person - Object type
|
|
624
|
-
@param {string[]} names - Array shorthand
|
|
625
|
-
@returns {void} - For functions with no return
|
|
164
|
+
export default config({
|
|
165
|
+
tsconfigPath: './tsconfig.json',
|
|
166
|
+
ignores: ['dist/**', 'build/**', 'public/**']
|
|
167
|
+
});
|
|
626
168
|
```
|
|
627
169
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
3. **Duplication with TypeScript**: This approach duplicates type information already in TypeScript
|
|
633
|
-
4. **Maintenance Overhead**: Types must be kept in sync between TypeScript and JSDoc
|
|
634
|
-
|
|
635
|
-
## โ ๏ธ Troubleshooting
|
|
636
|
-
|
|
637
|
-
### Peer Dependency Warnings
|
|
170
|
+
### TypeScript Library
|
|
171
|
+
```javascript
|
|
172
|
+
// eslint.config.mjs
|
|
173
|
+
import config from '@dmitryrechkin/eslint-standard/library';
|
|
638
174
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
175
|
+
export default config({
|
|
176
|
+
tsconfigPath: './tsconfig.json',
|
|
177
|
+
ignores: ['dist/**', 'examples/**']
|
|
178
|
+
});
|
|
642
179
|
```
|
|
643
180
|
|
|
644
|
-
###
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
| Option | Type | Default | Description |
|
|
657
|
-
|--------|------|---------|-------------|
|
|
658
|
-
| `tsconfigPath` | `string` | `'./tsconfig.json'` | Path to your TypeScript config file |
|
|
659
|
-
| `files` | `string[]` | `['**/*.{js,jsx,ts,tsx}']` | File patterns to lint |
|
|
660
|
-
| `ignores` | `string[]` | `['node_modules/**', 'dist/**']` | Patterns to ignore |
|
|
661
|
-
| `plugins` | `object` | `{}` | Additional ESLint plugins |
|
|
662
|
-
| `rules` | `object` | `{}` | Additional or overridden rules |
|
|
663
|
-
|
|
664
|
-
## ๐ Plugin Documentation
|
|
665
|
-
|
|
666
|
-
This configuration uses several powerful ESLint plugins:
|
|
667
|
-
|
|
668
|
-
- **[@typescript-eslint](https://typescript-eslint.io/)**: TypeScript-specific linting rules
|
|
669
|
-
- **[eslint-plugin-perfectionist](https://perfectionist.dev/)**: Auto-sorting for classes, imports, and more
|
|
670
|
-
- **[eslint-plugin-simple-import-sort](https://github.com/lydell/eslint-plugin-simple-import-sort)**: Simple and reliable import sorting
|
|
671
|
-
- **[@stylistic/eslint-plugin](https://eslint.style/)**: Stylistic formatting rules
|
|
672
|
-
- **[eslint-plugin-unused-imports](https://github.com/sweepline/eslint-plugin-unused-imports)**: Automatic unused import removal
|
|
181
|
+
### Node.js API
|
|
182
|
+
```javascript
|
|
183
|
+
// eslint.config.mjs
|
|
184
|
+
import config from '@dmitryrechkin/eslint-standard/aggressive';
|
|
185
|
+
|
|
186
|
+
export default config({
|
|
187
|
+
tsconfigPath: './tsconfig.json',
|
|
188
|
+
rules: {
|
|
189
|
+
'no-console': 'off', // Allow console in Node.js
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
```
|
|
673
193
|
|
|
674
194
|
## ๐ค Contributing
|
|
675
195
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
- ๐ [Report bugs](https://github.com/dmitryrechkin/eslint-standard/issues)
|
|
679
|
-
- ๐ก [Suggest new features](https://github.com/dmitryrechkin/eslint-standard/issues)
|
|
680
|
-
- ๐ง [Submit pull requests](https://github.com/dmitryrechkin/eslint-standard/pulls)
|
|
196
|
+
Issues and pull requests are welcome on [GitHub](https://github.com/dmitryrechkin/eslint-standard).
|
|
681
197
|
|
|
682
198
|
## ๐ License
|
|
683
199
|
|
|
684
|
-
MIT License - see
|
|
685
|
-
|
|
686
|
-
|
|
200
|
+
MIT License - see LICENSE file for details.
|