eslint-plugin-nextfriday 1.14.0 → 1.15.1
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/CHANGELOG.md +16 -0
- package/README.md +52 -22
- package/docs/rules/ENFORCE_SORTED_DESTRUCTURING.md +2 -0
- package/docs/rules/JSX_NO_NEWLINE_SINGLE_LINE_ELEMENTS.md +76 -0
- package/docs/rules/JSX_SORT_PROPS.md +58 -0
- package/docs/rules/SORT_EXPORTS.md +70 -0
- package/docs/rules/SORT_IMPORTS.md +80 -0
- package/docs/rules/SORT_TYPE_ALPHABETICALLY.md +106 -0
- package/docs/rules/SORT_TYPE_REQUIRED_FIRST.md +20 -46
- package/lib/index.cjs +880 -327
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +152 -26
- package/lib/index.d.ts +152 -26
- package/lib/index.js +882 -327
- package/lib/index.js.map +1 -1
- package/package.json +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# eslint-plugin-nextfriday
|
|
2
2
|
|
|
3
|
+
## 1.15.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#71](https://github.com/next-friday/eslint-plugin-nextfriday/pull/71) [`4831ea6`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/4831ea697e9dfe38361b3a3577b67692ea1cd862) Thanks [@joetakara](https://github.com/joetakara)! - Update docs: add fixable info to sorting rules, add bundled plugin configs section to README.
|
|
8
|
+
|
|
9
|
+
## 1.15.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#68](https://github.com/next-friday/eslint-plugin-nextfriday/pull/68) [`857906e`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/857906e5264ef87a988ba5429019c004360fa2a1) Thanks [@nextfridaydeveloper](https://github.com/nextfridaydeveloper)! - Add sort-imports, sort-exports, sort-type-alphabetically, jsx-sort-props, jsx-no-newline-single-line-elements rules. Add auto-fix to sorting rules. Bundle eslint-plugin-unicorn and eslint-plugin-sonarjs configs.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#69](https://github.com/next-friday/eslint-plugin-nextfriday/pull/69) [`2475fc5`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/2475fc5e7d80c2b158cddbed961dbb7e4e348188) Thanks [@joetakara](https://github.com/joetakara)! - Fix CJS compatibility for bundled eslint-plugin-sonarjs and eslint-plugin-unicorn configs.
|
|
18
|
+
|
|
3
19
|
## 1.14.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -46,6 +46,21 @@ export default [nextfriday.configs.nextjs];
|
|
|
46
46
|
export default [nextfriday.configs["nextjs/recommended"]];
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
#### Bundled Plugin Configs
|
|
50
|
+
|
|
51
|
+
Pre-configured configs for popular plugins. No extra install needed — they ship as dependencies.
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import nextfriday from "eslint-plugin-nextfriday";
|
|
55
|
+
|
|
56
|
+
export default [nextfriday.configs["react/recommended"], ...nextfriday.configs.sonarjs, ...nextfriday.configs.unicorn];
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
| Config | Plugin | Description |
|
|
60
|
+
| --------- | --------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
61
|
+
| `sonarjs` | eslint-plugin-sonarjs | SonarJS recommended rules for bug detection and code quality |
|
|
62
|
+
| `unicorn` | eslint-plugin-unicorn | Unicorn recommended rules (with `filename-case` and `prevent-abbreviations` off, `no-null` off in JSX/TSX) |
|
|
63
|
+
|
|
49
64
|
### Manual Configuration
|
|
50
65
|
|
|
51
66
|
If you prefer to configure rules manually:
|
|
@@ -94,19 +109,24 @@ export default [
|
|
|
94
109
|
"nextfriday/no-relative-imports": "error",
|
|
95
110
|
"nextfriday/prefer-import-type": "error",
|
|
96
111
|
"nextfriday/prefer-react-import-types": "error",
|
|
112
|
+
"nextfriday/sort-exports": "error",
|
|
113
|
+
"nextfriday/sort-imports": "error",
|
|
97
114
|
|
|
98
115
|
// Type Patterns
|
|
99
116
|
"nextfriday/prefer-named-param-types": "error",
|
|
100
117
|
"nextfriday/prefer-interface-over-inline-types": "error",
|
|
118
|
+
"nextfriday/sort-type-alphabetically": "error",
|
|
101
119
|
"nextfriday/sort-type-required-first": "error",
|
|
102
120
|
|
|
103
121
|
// React/JSX
|
|
104
122
|
"nextfriday/jsx-newline-between-elements": "error",
|
|
105
123
|
"nextfriday/jsx-no-inline-object-prop": "error",
|
|
124
|
+
"nextfriday/jsx-no-newline-single-line-elements": "error",
|
|
106
125
|
"nextfriday/jsx-no-non-component-function": "error",
|
|
107
126
|
"nextfriday/jsx-no-variable-in-callback": "error",
|
|
108
127
|
"nextfriday/jsx-require-suspense": "error",
|
|
109
128
|
"nextfriday/jsx-simple-props": "error",
|
|
129
|
+
"nextfriday/jsx-sort-props": "error",
|
|
110
130
|
"nextfriday/prefer-jsx-template-literals": "error",
|
|
111
131
|
"nextfriday/react-props-destructure": "error",
|
|
112
132
|
"nextfriday/enforce-props-suffix": "error",
|
|
@@ -179,7 +199,7 @@ module.exports = {
|
|
|
179
199
|
| [no-logic-in-params](docs/rules/NO_LOGIC_IN_PARAMS.md) | Disallow logic/conditions in function parameters - extract to const | ❌ |
|
|
180
200
|
| [enforce-hook-naming](docs/rules/ENFORCE_HOOK_NAMING.md) | Enforce 'use' prefix for functions in \*.hook.ts files | ❌ |
|
|
181
201
|
| [enforce-service-naming](docs/rules/ENFORCE_SERVICE_NAMING.md) | Enforce 'fetch' prefix for async functions in \*.service.ts files | ❌ |
|
|
182
|
-
| [enforce-sorted-destructuring](docs/rules/ENFORCE_SORTED_DESTRUCTURING.md) | Enforce alphabetical sorting of destructured properties |
|
|
202
|
+
| [enforce-sorted-destructuring](docs/rules/ENFORCE_SORTED_DESTRUCTURING.md) | Enforce alphabetical sorting of destructured properties | ✅ |
|
|
183
203
|
| [no-env-fallback](docs/rules/NO_ENV_FALLBACK.md) | Disallow fallback values for environment variables | ❌ |
|
|
184
204
|
| [no-inline-default-export](docs/rules/NO_INLINE_DEFAULT_EXPORT.md) | Disallow inline default exports - declare first, then export | ❌ |
|
|
185
205
|
| [no-direct-date](docs/rules/NO_DIRECT_DATE.md) | Disallow direct usage of Date constructor and methods | ❌ |
|
|
@@ -198,6 +218,8 @@ module.exports = {
|
|
|
198
218
|
| [no-relative-imports](docs/rules/NO_RELATIVE_IMPORTS.md) | Disallow relative imports with ../ - use absolute imports | ❌ |
|
|
199
219
|
| [prefer-import-type](docs/rules/PREFER_IMPORT_TYPE.md) | Enforce using 'import type' for type-only imports | ✅ |
|
|
200
220
|
| [prefer-react-import-types](docs/rules/PREFER_REACT_IMPORT_TYPES.md) | Enforce direct imports from 'react' instead of React.X | ✅ |
|
|
221
|
+
| [sort-exports](docs/rules/SORT_EXPORTS.md) | Enforce a consistent ordering of export groups | ✅ |
|
|
222
|
+
| [sort-imports](docs/rules/SORT_IMPORTS.md) | Enforce a consistent ordering of import groups | ✅ |
|
|
201
223
|
|
|
202
224
|
### Type Pattern Rules
|
|
203
225
|
|
|
@@ -205,22 +227,25 @@ module.exports = {
|
|
|
205
227
|
| -------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ------- |
|
|
206
228
|
| [prefer-named-param-types](docs/rules/PREFER_NAMED_PARAM_TYPES.md) | Enforce named types for function parameters with object types | ❌ |
|
|
207
229
|
| [prefer-interface-over-inline-types](docs/rules/PREFER_INTERFACE_OVER_INLINE_TYPES.md) | Enforce interface declarations over inline types for React props | ❌ |
|
|
208
|
-
| [sort-type-
|
|
230
|
+
| [sort-type-alphabetically](docs/rules/SORT_TYPE_ALPHABETICALLY.md) | Enforce A-Z sorting of properties within type groups | ✅ |
|
|
231
|
+
| [sort-type-required-first](docs/rules/SORT_TYPE_REQUIRED_FIRST.md) | Enforce required properties before optional in types/interfaces | ✅ |
|
|
209
232
|
|
|
210
233
|
### React/JSX Rules
|
|
211
234
|
|
|
212
|
-
| Rule
|
|
213
|
-
|
|
|
214
|
-
| [jsx-newline-between-elements](docs/rules/JSX_NEWLINE_BETWEEN_ELEMENTS.md)
|
|
215
|
-
| [jsx-no-inline-object-prop](docs/rules/JSX_NO_INLINE_OBJECT_PROP.md)
|
|
216
|
-
| [jsx-no-
|
|
217
|
-
| [jsx-no-
|
|
218
|
-
| [jsx-
|
|
219
|
-
| [jsx-
|
|
220
|
-
| [
|
|
221
|
-
| [
|
|
222
|
-
| [
|
|
223
|
-
| [
|
|
235
|
+
| Rule | Description | Fixable |
|
|
236
|
+
| ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------- |
|
|
237
|
+
| [jsx-newline-between-elements](docs/rules/JSX_NEWLINE_BETWEEN_ELEMENTS.md) | Require empty lines between sibling multi-line JSX elements | ✅ |
|
|
238
|
+
| [jsx-no-inline-object-prop](docs/rules/JSX_NO_INLINE_OBJECT_PROP.md) | Disallow inline object literals in JSX props | ❌ |
|
|
239
|
+
| [jsx-no-newline-single-line-elements](docs/rules/JSX_NO_NEWLINE_SINGLE_LINE_ELEMENTS.md) | Disallow empty lines between single-line sibling JSX elements | ✅ |
|
|
240
|
+
| [jsx-no-non-component-function](docs/rules/JSX_NO_NON_COMPONENT_FUNCTION.md) | Disallow non-component functions at top level in .tsx/.jsx files | ❌ |
|
|
241
|
+
| [jsx-no-variable-in-callback](docs/rules/JSX_NO_VARIABLE_IN_CALLBACK.md) | Disallow variable declarations inside callback functions in JSX | ❌ |
|
|
242
|
+
| [jsx-require-suspense](docs/rules/JSX_REQUIRE_SUSPENSE.md) | Require lazy-loaded components to be wrapped in Suspense | ❌ |
|
|
243
|
+
| [jsx-simple-props](docs/rules/JSX_SIMPLE_PROPS.md) | Enforce simple prop values (strings, variables, callbacks, ReactNode) | ❌ |
|
|
244
|
+
| [jsx-sort-props](docs/rules/JSX_SORT_PROPS.md) | Enforce JSX props are sorted by value type | ❌ |
|
|
245
|
+
| [prefer-jsx-template-literals](docs/rules/PREFER_JSX_TEMPLATE_LITERALS.md) | Enforce template literals instead of mixing text and JSX expressions | ✅ |
|
|
246
|
+
| [react-props-destructure](docs/rules/REACT_PROPS_DESTRUCTURE.md) | Enforce destructuring props inside React component body | ❌ |
|
|
247
|
+
| [enforce-props-suffix](docs/rules/ENFORCE_PROPS_SUFFIX.md) | Enforce 'Props' suffix for interfaces and types in \*.tsx files | ❌ |
|
|
248
|
+
| [enforce-readonly-component-props](docs/rules/ENFORCE_READONLY_COMPONENT_PROPS.md) | Enforce Readonly wrapper for React component props | ✅ |
|
|
224
249
|
|
|
225
250
|
### Next.js Rules
|
|
226
251
|
|
|
@@ -234,14 +259,14 @@ module.exports = {
|
|
|
234
259
|
|
|
235
260
|
| Preset | Severity | Base Rules | JSX Rules | Next.js Rules | Total Rules |
|
|
236
261
|
| -------------------- | -------- | ---------- | --------- | ------------- | ----------- |
|
|
237
|
-
| `base` | warn |
|
|
238
|
-
| `base/recommended` | error |
|
|
239
|
-
| `react` | warn |
|
|
240
|
-
| `react/recommended` | error |
|
|
241
|
-
| `nextjs` | warn |
|
|
242
|
-
| `nextjs/recommended` | error |
|
|
262
|
+
| `base` | warn | 33 | 0 | 0 | 33 |
|
|
263
|
+
| `base/recommended` | error | 33 | 0 | 0 | 33 |
|
|
264
|
+
| `react` | warn | 33 | 14 | 0 | 47 |
|
|
265
|
+
| `react/recommended` | error | 33 | 14 | 0 | 47 |
|
|
266
|
+
| `nextjs` | warn | 33 | 14 | 1 | 48 |
|
|
267
|
+
| `nextjs/recommended` | error | 33 | 14 | 1 | 48 |
|
|
243
268
|
|
|
244
|
-
### Base Configuration Rules (
|
|
269
|
+
### Base Configuration Rules (33 rules)
|
|
245
270
|
|
|
246
271
|
Included in `base`, `base/recommended`, and all other presets:
|
|
247
272
|
|
|
@@ -274,9 +299,12 @@ Included in `base`, `base/recommended`, and all other presets:
|
|
|
274
299
|
- `nextfriday/prefer-named-param-types`
|
|
275
300
|
- `nextfriday/prefer-react-import-types`
|
|
276
301
|
- `nextfriday/require-explicit-return-type`
|
|
302
|
+
- `nextfriday/sort-exports`
|
|
303
|
+
- `nextfriday/sort-imports`
|
|
304
|
+
- `nextfriday/sort-type-alphabetically`
|
|
277
305
|
- `nextfriday/sort-type-required-first`
|
|
278
306
|
|
|
279
|
-
### JSX Rules (
|
|
307
|
+
### JSX Rules (14 rules)
|
|
280
308
|
|
|
281
309
|
Additionally included in `react`, `react/recommended`, `nextjs`, `nextjs/recommended`:
|
|
282
310
|
|
|
@@ -284,11 +312,13 @@ Additionally included in `react`, `react/recommended`, `nextjs`, `nextjs/recomme
|
|
|
284
312
|
- `nextfriday/enforce-readonly-component-props`
|
|
285
313
|
- `nextfriday/jsx-newline-between-elements`
|
|
286
314
|
- `nextfriday/jsx-no-inline-object-prop`
|
|
315
|
+
- `nextfriday/jsx-no-newline-single-line-elements`
|
|
287
316
|
- `nextfriday/jsx-no-non-component-function`
|
|
288
317
|
- `nextfriday/jsx-no-variable-in-callback`
|
|
289
318
|
- `nextfriday/jsx-pascal-case`
|
|
290
319
|
- `nextfriday/jsx-require-suspense`
|
|
291
320
|
- `nextfriday/jsx-simple-props`
|
|
321
|
+
- `nextfriday/jsx-sort-props`
|
|
292
322
|
- `nextfriday/prefer-interface-over-inline-types`
|
|
293
323
|
- `nextfriday/prefer-jsx-template-literals`
|
|
294
324
|
- `nextfriday/react-props-destructure`
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Enforce alphabetical sorting of destructured properties with defaults first.
|
|
4
4
|
|
|
5
|
+
This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
6
|
+
|
|
5
7
|
## Rule Details
|
|
6
8
|
|
|
7
9
|
This rule enforces that object destructuring properties are sorted alphabetically, with properties that have default values coming first. Both groups (defaults and non-defaults) are sorted alphabetically (A-Z).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# jsx-no-newline-single-line-elements
|
|
2
|
+
|
|
3
|
+
Disallow empty lines between single-line sibling JSX elements.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule enforces that sibling JSX elements which are both single-line should not have empty lines between them. Single-line elements should be compact and grouped together.
|
|
8
|
+
|
|
9
|
+
Use with `jsx-newline-between-elements` which requires empty lines between multi-line siblings.
|
|
10
|
+
|
|
11
|
+
### Why?
|
|
12
|
+
|
|
13
|
+
1. **Readability**: Single-line elements that are visually similar should be grouped together without gaps
|
|
14
|
+
2. **Consistency**: Prevents inconsistent spacing between elements of the same visual weight
|
|
15
|
+
3. **Complementary**: Works alongside `jsx-newline-between-elements` to create clear visual separation only where it matters
|
|
16
|
+
|
|
17
|
+
## Examples
|
|
18
|
+
|
|
19
|
+
### ❌ Incorrect
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
// Bad: Unnecessary empty line between single-line siblings
|
|
23
|
+
<div>
|
|
24
|
+
<Panel id="courses">Courses</Panel>
|
|
25
|
+
|
|
26
|
+
<Panel id="news">News</Panel>
|
|
27
|
+
</div>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
// Bad: Empty lines between single-line list items
|
|
32
|
+
<ul>
|
|
33
|
+
<li>Item 1</li>
|
|
34
|
+
|
|
35
|
+
<li>Item 2</li>
|
|
36
|
+
|
|
37
|
+
<li>Item 3</li>
|
|
38
|
+
</ul>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### ✅ Correct
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
// Good: Single-line siblings are compact
|
|
45
|
+
<div>
|
|
46
|
+
<Panel id="courses">Courses</Panel>
|
|
47
|
+
<Panel id="news">News</Panel>
|
|
48
|
+
</div>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
// Good: Multi-line sibling has empty line (handled by jsx-newline-between-elements)
|
|
53
|
+
<div>
|
|
54
|
+
<Panel id="overview">
|
|
55
|
+
<div className="grid gap-8">
|
|
56
|
+
<div>Content</div>
|
|
57
|
+
</div>
|
|
58
|
+
</Panel>
|
|
59
|
+
|
|
60
|
+
<Panel id="courses">Courses</Panel>
|
|
61
|
+
<Panel id="news">News</Panel>
|
|
62
|
+
</div>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
// Good: Self-closing components without empty lines
|
|
67
|
+
<div>
|
|
68
|
+
<Header />
|
|
69
|
+
<Main />
|
|
70
|
+
<Footer />
|
|
71
|
+
</div>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## When Not To Use It
|
|
75
|
+
|
|
76
|
+
If you prefer empty lines between all sibling JSX elements regardless of their line count, you can disable this rule.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# jsx-sort-props
|
|
2
|
+
|
|
3
|
+
Enforce JSX props are sorted by value type.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule enforces a consistent ordering of JSX props based on the type of their value. Props must appear in the following order:
|
|
8
|
+
|
|
9
|
+
1. **String** - String literals and template literals
|
|
10
|
+
2. **Number/Boolean/Null** - Numeric literals, boolean literals, null, and undefined
|
|
11
|
+
3. **Object/Array** - Inline objects and arrays
|
|
12
|
+
4. **Function** - Arrow functions and function expressions
|
|
13
|
+
5. **JSX Element** - JSX elements and fragments
|
|
14
|
+
6. **Shorthand boolean** - Props with no value (e.g., `disabled`)
|
|
15
|
+
|
|
16
|
+
Props with values that cannot be statically determined (variables, member expressions, call expressions, etc.) are skipped and do not affect the ordering check. Spread attributes (`{...props}`) reset the ordering context.
|
|
17
|
+
|
|
18
|
+
### Why?
|
|
19
|
+
|
|
20
|
+
- **Readability**: Grouping props by type makes components easier to scan
|
|
21
|
+
- **Consistency**: Enforces a uniform prop ordering convention across the codebase
|
|
22
|
+
- **Predictability**: Developers know where to find specific prop types at a glance
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
### ❌ Incorrect
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
<Component disabled title="hello" />
|
|
30
|
+
<Component onClick={() => {}} count={42} />
|
|
31
|
+
<Component icon={<Icon />} style={{ color: "red" }} />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### ✅ Correct
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<Component
|
|
38
|
+
title="hello"
|
|
39
|
+
count={100}
|
|
40
|
+
style={{ color: "red" }}
|
|
41
|
+
onClick={() => handleClick()}
|
|
42
|
+
icon={<HomeIcon />}
|
|
43
|
+
disabled
|
|
44
|
+
/>
|
|
45
|
+
|
|
46
|
+
<Component title="hello" count={42} disabled />
|
|
47
|
+
|
|
48
|
+
<Component value={someVar} disabled />
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## When Not To Use It
|
|
52
|
+
|
|
53
|
+
- If your team prefers alphabetical or custom prop ordering
|
|
54
|
+
- If you use a different prop sorting convention
|
|
55
|
+
|
|
56
|
+
## Related Rules
|
|
57
|
+
|
|
58
|
+
- [jsx-simple-props](./JSX_SIMPLE_PROPS.md) - Enforce simple prop values
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# sort-exports
|
|
2
|
+
|
|
3
|
+
Enforce a consistent ordering of export groups.
|
|
4
|
+
|
|
5
|
+
This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
6
|
+
|
|
7
|
+
## Rule Details
|
|
8
|
+
|
|
9
|
+
This rule enforces that named export statements (without declarations) are grouped and ordered by their source type. It does not enforce alphabetical sorting within groups.
|
|
10
|
+
|
|
11
|
+
### Why?
|
|
12
|
+
|
|
13
|
+
1. **Readability**: Grouping exports by source type makes barrel files and re-export modules easier to scan
|
|
14
|
+
2. **Consistency**: A predictable export order reduces merge conflicts and code review friction
|
|
15
|
+
3. **Separation of concerns**: Re-exports from external/internal sources vs local exports serve different purposes
|
|
16
|
+
|
|
17
|
+
### Export Group Order
|
|
18
|
+
|
|
19
|
+
1. **External/alias re-exports** — source matches a package name or alias (`@/`, `~/`, `#`) (e.g., `export { foo } from "react"`)
|
|
20
|
+
2. **Relative re-exports** — source starts with `.` (e.g., `export { bar } from "../bar"`)
|
|
21
|
+
3. **Local exports** — no source (e.g., `export { baz }`)
|
|
22
|
+
|
|
23
|
+
Skipped (breaks contiguity): `export default`, `export *`, `export const/function/class` (declarations).
|
|
24
|
+
|
|
25
|
+
Non-contiguous exports (separated by other statements) are checked independently.
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
### ❌ Incorrect
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// Bad: Local before re-export
|
|
33
|
+
export { bar };
|
|
34
|
+
export { foo } from "react";
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
// Bad: Relative before external
|
|
39
|
+
export { bar } from "../bar";
|
|
40
|
+
export { foo } from "react";
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### ✅ Correct
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// Good: All 3 groups in correct order
|
|
47
|
+
export { foo } from "@/lib/foo";
|
|
48
|
+
export { bar } from "../bar";
|
|
49
|
+
export { baz };
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// Good: Non-contiguous exports are independent
|
|
54
|
+
export { foo } from "react";
|
|
55
|
+
|
|
56
|
+
const x = 1;
|
|
57
|
+
|
|
58
|
+
export { bar };
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
// Good: Export declarations break contiguity
|
|
63
|
+
export const x = 1;
|
|
64
|
+
export { foo } from "./foo";
|
|
65
|
+
export { bar };
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## When Not To Use It
|
|
69
|
+
|
|
70
|
+
If you prefer a different export ordering convention or don't want to enforce any particular order for exports, you can disable this rule.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# sort-imports
|
|
2
|
+
|
|
3
|
+
Enforce a consistent ordering of import groups.
|
|
4
|
+
|
|
5
|
+
This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
6
|
+
|
|
7
|
+
## Rule Details
|
|
8
|
+
|
|
9
|
+
This rule enforces that import statements are grouped and ordered by their source type. It does not enforce alphabetical sorting within groups.
|
|
10
|
+
|
|
11
|
+
### Why?
|
|
12
|
+
|
|
13
|
+
1. **Readability**: Grouping imports by source type makes it easy to scan dependencies at a glance
|
|
14
|
+
2. **Consistency**: A predictable import order reduces merge conflicts and code review friction
|
|
15
|
+
3. **Separation of concerns**: Side effects, platform modules, third-party packages, internal aliases, and relative imports serve different purposes
|
|
16
|
+
|
|
17
|
+
### Import Group Order
|
|
18
|
+
|
|
19
|
+
1. **Side-effect imports** — no specifiers (e.g., `import "./setup"`)
|
|
20
|
+
2. **Node.js builtins** — `node:` prefix or known builtin names (e.g., `import fs from "node:fs"`)
|
|
21
|
+
3. **External packages** — scoped or plain package names (e.g., `import React from "react"`)
|
|
22
|
+
4. **Internal aliases** — paths starting with `@/`, `~/`, or `#` (e.g., `import { utils } from "@/lib/utils"`)
|
|
23
|
+
5. **Relative imports** — paths starting with `.` (e.g., `import { foo } from "../foo"`)
|
|
24
|
+
|
|
25
|
+
Type-only imports (`import type`) are skipped and do not affect ordering.
|
|
26
|
+
|
|
27
|
+
Non-contiguous imports (separated by other statements) are checked independently.
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
### ❌ Incorrect
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
// Bad: Relative before external
|
|
35
|
+
import { foo } from "../foo";
|
|
36
|
+
import React from "react";
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// Bad: External before builtin
|
|
41
|
+
import React from "react";
|
|
42
|
+
import fs from "node:fs";
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// Bad: Side-effect after external
|
|
47
|
+
import React from "react";
|
|
48
|
+
import "./setup";
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### ✅ Correct
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
// Good: All 5 groups in correct order
|
|
55
|
+
import "./setup";
|
|
56
|
+
import fs from "node:fs";
|
|
57
|
+
import React from "react";
|
|
58
|
+
import { utils } from "@/lib/utils";
|
|
59
|
+
import { foo } from "../foo";
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// Good: Type imports can appear anywhere
|
|
64
|
+
import type { FC } from "react";
|
|
65
|
+
import { foo } from "../foo";
|
|
66
|
+
import React from "react";
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
// Good: Non-contiguous imports are independent
|
|
71
|
+
import React from "react";
|
|
72
|
+
|
|
73
|
+
const x = 1;
|
|
74
|
+
|
|
75
|
+
import { foo } from "../foo";
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## When Not To Use It
|
|
79
|
+
|
|
80
|
+
If you use a different import sorting tool (e.g., `eslint-plugin-simple-import-sort`) or prefer a different group ordering, you can disable this rule.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# sort-type-alphabetically
|
|
2
|
+
|
|
3
|
+
Enforce alphabetical sorting of properties within required and optional groups in TypeScript interfaces and type aliases.
|
|
4
|
+
|
|
5
|
+
This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
6
|
+
|
|
7
|
+
## Rule Details
|
|
8
|
+
|
|
9
|
+
This rule enforces that TypeScript interface and type alias properties are sorted alphabetically (A-Z) within their respective groups (required and optional). It checks each group independently.
|
|
10
|
+
|
|
11
|
+
### Why?
|
|
12
|
+
|
|
13
|
+
1. **Readability**: Alphabetical ordering makes properties easier to find
|
|
14
|
+
2. **Consistency**: A predictable ordering reduces cognitive load during code review
|
|
15
|
+
3. **Maintainability**: Clear structure makes it easier to add or remove properties
|
|
16
|
+
|
|
17
|
+
### Sorting Order
|
|
18
|
+
|
|
19
|
+
Properties within each group are sorted alphabetically A-Z:
|
|
20
|
+
|
|
21
|
+
1. **Required properties** sorted A-Z among themselves
|
|
22
|
+
2. **Optional properties** sorted A-Z among themselves
|
|
23
|
+
|
|
24
|
+
Use with `sort-type-required-first` to also enforce required properties come before optional.
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
|
|
28
|
+
### ❌ Incorrect
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// Bad: Required not sorted A-Z
|
|
32
|
+
interface Props {
|
|
33
|
+
src: string;
|
|
34
|
+
alt: string;
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// Bad: Optional not sorted A-Z
|
|
40
|
+
interface Props {
|
|
41
|
+
b?: number;
|
|
42
|
+
a?: string;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// Bad: Required group not sorted A-Z
|
|
48
|
+
interface HeroBannerRootProps {
|
|
49
|
+
size: "detail" | "highlight" | "main";
|
|
50
|
+
alt: string;
|
|
51
|
+
src: string;
|
|
52
|
+
className?: string;
|
|
53
|
+
label?: string;
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### ✅ Correct
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
// Good: Required A-Z, optional A-Z
|
|
61
|
+
interface HeroBannerRootProps {
|
|
62
|
+
alt: string;
|
|
63
|
+
size: "detail" | "highlight" | "main";
|
|
64
|
+
src: string;
|
|
65
|
+
className?: string;
|
|
66
|
+
label?: string;
|
|
67
|
+
onClick?: () => void;
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
// Good: All required, sorted A-Z
|
|
73
|
+
interface Props {
|
|
74
|
+
a: string;
|
|
75
|
+
b: number;
|
|
76
|
+
c: boolean;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
// Good: All optional, sorted A-Z
|
|
82
|
+
interface Props {
|
|
83
|
+
a?: string;
|
|
84
|
+
b?: number;
|
|
85
|
+
c?: boolean;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// Good: Type alias with A-Z within groups
|
|
91
|
+
type Props = {
|
|
92
|
+
alt: string;
|
|
93
|
+
size: string;
|
|
94
|
+
src: string;
|
|
95
|
+
label?: string;
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## When Not To Use It
|
|
100
|
+
|
|
101
|
+
If you prefer a different sorting strategy for type properties or don't want to enforce alphabetical ordering, you can disable this rule.
|
|
102
|
+
|
|
103
|
+
## Further Reading
|
|
104
|
+
|
|
105
|
+
- [TypeScript Interfaces](https://www.typescriptlang.org/docs/handbook/2/objects.html)
|
|
106
|
+
- [TypeScript Type Aliases](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-aliases)
|