You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|`minimize-complexflows`| Enforces simplified control flow by limiting recursion and nesting depth, and detecting direct or lexically scoped recursion to improve readability and reduce error potential. |
12
12
|`avoid-runtime-heap-allocation`| Discourages heap allocation of common data structures (arrays, objects, Maps, Sets) within function bodies, especially in loops, to promote reuse and reduce GC pressure. |
13
13
|`limit-reference-depth`| Restricts the depth of chained property access and enforces optional chaining to prevent runtime errors, improve null safety, and encourage safer access patterns in deeply nested data structures. |
14
-
|`keep-functions-concise`| Enforces a maximum number of lines per function, with options to skip blank lines and comments, to promote readability, maintainability, and concise logic blocks. ||`fixed-loop-bounds`| Enforces that loops have clearly defined termination conditions to prevent infinite loops. |
14
+
|`keep-functions-concise`| Enforces a maximum number of lines per function, with options to skip blank lines and comments, to promote readability, maintainability, and concise logic blocks. |
15
+
|`fixed-loop-bounds`| Enforces that loops have clearly defined termination conditions to prevent infinite loops. |
15
16
|`no-disable-important-rules`| Discourages disabling all rules or specific "important" ESLint rules, promoting proactive resolution of linter/compiler warnings. |
16
17
|`limit-data-scope`| Enforces best practices for data scoping, such as avoiding global object modification and preferring narrower variable scopes. |
18
+
||
17
19
18
20
### Configuration
19
21
@@ -57,6 +59,24 @@ export default [
57
59
/* options */
58
60
},
59
61
],
62
+
'hub/fixed-loop-bounds': [
63
+
'warn',
64
+
{
65
+
/* options */
66
+
},
67
+
],
68
+
'hub/no-disable-important-rules': [
69
+
'warn',
70
+
{
71
+
/* options */
72
+
},
73
+
],
74
+
'hub/limit-data-scope': [
75
+
'warn',
76
+
{
77
+
/* options */
78
+
},
79
+
],
60
80
'hub/limit-reference-depth': [
61
81
'warn',
62
82
{
@@ -769,253 +789,7 @@ const config = {
769
789
};
770
790
```
771
791
772
-
### 3. fixed-loop-bounds
773
-
774
-
**Description:**
775
-
This rule helps prevent infinite loops by ensuring that `while`, `do...while`, and `for` loops have clearly defined and reachable termination conditions. It specifically targets loops that use `true` as a condition or rely on external flags that are not modified within the loop body.
776
-
777
-
**Rationale:**
778
-
Infinite loops can cause applications to hang, consume excessive resources, and are a common source of bugs. Statically analyzing loop conditions helps catch these potential issues early.
779
-
780
-
**Options:**
781
-
The rule accepts an object with the following optional properties:
782
-
783
-
-`disallowInfiniteWhile` (boolean, default: `true`): If true, flags `while(true)`, `do...while(true)`, `for(;;)`, and `for(;true;)` loops that do not have an effective break statement within their body.
784
-
-`disallowExternalFlagLoops` (boolean, default: `true`): If true, flags `while` or `do...while` loops whose condition is an identifier (or its negation like `!flag`) that is not reassigned or updated within the loop's body.
785
-
786
-
**Important Implementation Details:**
787
-
788
-
- The rule performs static analysis to detect `break` statements that effectively terminate the loop
789
-
- It handles labeled break statements correctly
790
-
- It ignores breaks inside nested functions as they don't affect the outer loop
791
-
- For external flag detection, it checks for assignment expressions (`flag = value`) and update expressions (`flag++`, `++flag`, `flag--`, `--flag`)
792
-
- Modifications inside nested functions are not considered as they operate in different scopes
793
-
794
-
**Examples of Incorrect Code:**
795
-
796
-
```javascript
797
-
// Incorrect: while(true) without a break
798
-
while (true) {
799
-
console.log('potentially infinite');
800
-
// No break statement found
801
-
}
802
-
803
-
// Incorrect: for(;;) without a break
804
-
for (;;) {
805
-
// This loop will run forever
806
-
performTask();
807
-
}
808
-
809
-
// Incorrect: for loop with true condition but no break
810
-
for (; true; ) {
811
-
console.log('infinite loop');
812
-
}
813
-
814
-
// Incorrect: External flag not modified within the loop
815
-
let keepRunning =true;
816
-
while (keepRunning) {
817
-
// 'keepRunning' is never set to false inside this loop
818
-
performTask();
819
-
}
820
-
821
-
// Incorrect: Negated flag condition not modified
822
-
let shouldStop =false;
823
-
while (!shouldStop) {
824
-
// 'shouldStop' is never set to true inside this loop
825
-
doWork();
826
-
}
827
-
828
-
// Incorrect: do-while with true condition and no break
829
-
do {
830
-
processData();
831
-
} while (true); // No break statement in the body
832
-
```
833
-
834
-
**Examples of Correct Code:**
835
-
836
-
```javascript
837
-
// Correct: while(true) with a break
838
-
while (true) {
839
-
if (conditionMet()) {
840
-
break;
841
-
}
842
-
console.log('looping');
843
-
}
844
-
845
-
// Correct: for loop with a clear condition
846
-
for (let i =0; i <10; i++) {
847
-
console.log(i);
848
-
}
849
-
850
-
// Correct: External flag modified within the loop (assignment)
851
-
let processNext =true;
852
-
while (processNext) {
853
-
if (!processItem()) {
854
-
processNext =false; // Flag is modified via assignment
855
-
}
856
-
}
857
-
858
-
// Correct: External flag modified within the loop (update expression)
859
-
let counter =10;
860
-
while (counter) {
861
-
performTask();
862
-
counter--; // Flag is modified via update expression
863
-
}
864
-
865
-
// Correct: Labeled break statement
866
-
outerLoop:while (true) {
867
-
for (let i =0; i <5; i++) {
868
-
if (shouldExit()) {
869
-
break outerLoop; // Correctly targets the outer loop
870
-
}
871
-
}
872
-
}
873
-
874
-
// Correct: Break inside nested scope but not nested function
875
-
while (true) {
876
-
{
877
-
if (condition) {
878
-
break; // This break correctly exits the while loop
879
-
}
880
-
}
881
-
}
882
-
```
883
-
884
-
**When Not To Use It:**
885
-
You might consider disabling `disallowExternalFlagLoops` if you have loops where the controlling flag is intentionally modified by asynchronous operations or in a deeply nested utility function whose side effects on the flag are not easily detectable by static analysis (though this is generally an anti-pattern for loop control).
886
-
887
-
### 4. no-disable-important-rules
888
-
889
-
**Description:**
890
-
This rule discourages the use of ESLint disable comments (`/* eslint-disable */`, `// eslint-disable-line`, `// eslint-disable-next-line`) in two scenarios:
891
-
892
-
1. When they are used to disable all rules (blanket disable).
893
-
2. When they are used to disable a specific set of predefined "important" rules.
894
-
895
-
The default important rules are: `no-unused-vars`, `no-console`, `no-undef`, and `eqeqeq`.
896
-
897
-
**Rationale:**
898
-
Warnings from linters and compilers often highlight potential bugs, performance issues, or security vulnerabilities. Disabling these warnings without addressing the underlying issue can lead to technical debt and more significant problems later. This rule encourages developers to fix warnings or, if a disable is truly necessary, to be specific and provide justification.
899
-
900
-
**Options:**
901
-
The rule accepts an object with the following optional property:
902
-
903
-
-`importantRules` (array of strings): Allows you to override the default list of "important" rule names that should not be disabled.
904
-
-**Default important rules:**`['no-unused-vars', 'no-console', 'no-undef', 'eqeqeq']`
/* eslint-disable */// INCORRECT: Blanket disable of all rules
920
-
functionmessyCode() {
921
-
var x =10; // Would normally warn for 'no-unused-vars'
922
-
console.log('Debug message left in code'); // Would normally warn for 'no-console'
923
-
}
924
-
925
-
// eslint-disable-next-line
926
-
constanotherBlanket=true; // INCORRECT: Blanket disable for the next line
927
-
928
-
// eslint-disable-line
929
-
constyetAnother=false; // INCORRECT: Blanket disable for current line
930
-
931
-
// eslint-disable-next-line no-unused-vars
932
-
constmyVar='I am actually used later'; // INCORRECT: Disabling an important rule
933
-
934
-
/* eslint-disable no-console, no-undef */// INCORRECT: Disabling multiple important rules
935
-
console.info('This should be logged via a proper logger');
936
-
someUndefinedVariable = value;
937
-
/* eslint-enable no-console, no-undef */
938
-
939
-
// eslint-disable-next-line eqeqeq
940
-
if (value =='test') {
941
-
// INCORRECT: Disabling important rule 'eqeqeq'
942
-
doSomething();
943
-
}
944
-
```
945
-
946
-
**Examples of Correct Code:**
947
-
948
-
```javascript
949
-
// Correct: No disable comments, addressing issues directly
950
-
functioncleanCode() {
951
-
constx=10;
952
-
logger.info('Using proper logging instead of console'); // Fixed instead of disabled
953
-
return x; // Using the variable instead of leaving it unused
954
-
}
955
-
956
-
// Correct: Disabling a specific, non-important rule with justification
957
-
// eslint-disable-next-line some-other-plugin/some-specific-rule -- Justification for this specific case
958
-
doSomethingSpecific();
959
-
960
-
// Correct: Using strict equality instead of disabling eqeqeq
961
-
if (value ==='test') {
962
-
// Fixed the == vs === issue
963
-
doSomething();
964
-
}
965
-
966
-
// Correct: Properly declaring variables instead of disabling no-undef
967
-
constsomeVariable='defined value'; // Declared instead of leaving undefined
968
-
969
-
// Correct: Using the variable instead of disabling no-unused-vars
970
-
constimportantData=fetchData();
971
-
processData(importantData); // Actually using the variable
972
-
```
973
-
974
-
**Best Practices:**
975
-
976
-
-**Strict ESLint/TS Compiler Setups:** Projects should aim for the strictest possible ESLint configurations and TypeScript compiler options (e.g., `strict: true` in `tsconfig.json`).
977
-
-**Address Warnings Early:** Treating warnings as errors forces developers to address them immediately, preventing technical debt.
978
-
-**Document Disable Reasons:** Any `eslint-disable` comment should be accompanied by a clear explanation of why it's necessary.
979
-
980
-
**When Not To Use It:**
981
-
This rule might be overly restrictive during initial project scaffolding or large refactors. In such cases, it can be temporarily set to "warn" or disabled, but should be re-enabled as soon as possible.
982
-
983
-
### 5. limit-data-scope
984
-
985
-
**Description:**
986
-
Enforces best practices for data scoping, such as avoiding global object modification and preferring narrower variable scopes.
987
-
988
-
**Rationale:**
989
-
Proper data scoping helps prevent naming conflicts, makes code more maintainable, and reduces the risk of unintended side effects.
990
-
991
-
**Examples of Incorrect Code:**
992
-
993
-
```javascript
994
-
// Incorrect: Modifying global objects
995
-
global.myVariable='value';
996
-
997
-
// Incorrect: Using var in block scope where let/const would be better
998
-
if (condition) {
999
-
var result =processData();
1000
-
}
1001
-
```
1002
-
1003
-
**Examples of Correct Code:**
1004
-
1005
-
```javascript
1006
-
// Correct: Using appropriate scoping
1007
-
if (condition) {
1008
-
constresult=processData();
1009
-
// Use result within this scope
1010
-
}
1011
-
1012
-
// Correct: Avoiding global modifications
1013
-
constconfig= {
1014
-
myVariable:'value',
1015
-
};
1016
-
```
1017
-
1018
-
### `hub/limit-reference-depth`
792
+
### 6. limit-reference-depth
1019
793
1020
794
**Description**: Limits the depth of chained property access and enforces optional chaining to prevent runtime errors. This rule helps avoid brittle code that can crash when encountering null or undefined values in property chains, encouraging safer access patterns and better error handling.
1021
795
@@ -1349,7 +1123,7 @@ return config?.env?.settings?.meta?.internal?.key?.value; // Too complex
**Description**: Enforces a maximum number of lines per function to promote clean, modular code and better maintainability. This rule helps prevent monolithic functions that are hard to read, test, and debug by encouraging developers to break down large functions into smaller, focused, and reusable helper functions.
0 commit comments