@viclafouch/eslint-config-viclafouch 4.22.1-beta.5 → 4.22.1-beta.7
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/.claude/settings.local.json +3 -1
- package/CLAUDE.md +14 -9
- package/README.md +3 -9
- package/bin/init.js +2 -2
- package/index.d.ts +0 -9
- package/index.mjs +0 -1
- package/package.json +1 -1
- package/rules/react.mjs +33 -1
- package/rules/typescript.mjs +56 -2
- package/templates/nextjs.js +0 -2
- package/templates/react.js +0 -2
- package/better-tailwindcss.mjs +0 -32
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
"Bash(git commit -m \"$\\(cat <<''EOF''\nfeat: update dependencies and refactor next config to flat config\n\n- Update all dependencies to latest versions\n- Refactor next.mjs to use nextPlugin.configs.recommended directly\n- Remove @eslint/eslintrc FlatCompat dependency\n- Reorganize exports alphabetically in index.mjs\n- Add ignores for *.d.ts files in eslint.config.mjs\n- Add coding conventions section to CLAUDE.md\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
14
14
|
"WebSearch",
|
|
15
15
|
"Bash(npx eslint:*)",
|
|
16
|
-
"Bash(git -C /Users/victordelafouchardiere/Desktop/eslint-config-viclafouch status)"
|
|
16
|
+
"Bash(git -C /Users/victordelafouchardiere/Desktop/eslint-config-viclafouch status)",
|
|
17
|
+
"Bash(git -C /Users/victordelafouchardiere/Desktop/eslint-config-viclafouch add -A)",
|
|
18
|
+
"Bash(git -C /Users/victordelafouchardiere/Desktop/eslint-config-viclafouch commit -m \"$\\(cat <<''EOF''\nchore: remove Tailwind CSS configuration\n\n- Remove better-tailwindcss.mjs and betterTailwindcssConfig export\n- Update README, CLAUDE.md, and CLI templates\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")"
|
|
17
19
|
]
|
|
18
20
|
}
|
|
19
21
|
}
|
package/CLAUDE.md
CHANGED
|
@@ -10,7 +10,6 @@ This is a reusable ESLint and Prettier configuration package published on npm. I
|
|
|
10
10
|
- TypeScript-first configuration (all projects are TypeScript by default)
|
|
11
11
|
- ES6+, JSX/TSX support
|
|
12
12
|
- React.js and Next.js frameworks
|
|
13
|
-
- Tailwind CSS v4 linting
|
|
14
13
|
- Promise handling and best practices
|
|
15
14
|
- Unicorn plugin for modern JavaScript
|
|
16
15
|
|
|
@@ -34,7 +33,6 @@ This is a reusable ESLint and Prettier configuration package published on npm. I
|
|
|
34
33
|
| `hooks.mjs` | React Hooks rules (rules-of-hooks, exhaustive-deps, useState naming) |
|
|
35
34
|
| `imports.mjs` | Import sorting with simple-import-sort in priority groups |
|
|
36
35
|
| `prettier.mjs` | Prettier integration via eslint-plugin-prettier |
|
|
37
|
-
| `better-tailwindcss.mjs` | Tailwind CSS v4 linting (function accepting `{ entryPoint }`) |
|
|
38
36
|
|
|
39
37
|
### Rules Directory
|
|
40
38
|
|
|
@@ -45,6 +43,15 @@ This is a reusable ESLint and Prettier configuration package published on npm. I
|
|
|
45
43
|
| `rules/react.mjs` | React-specific rules |
|
|
46
44
|
| `rules/react-hooks.mjs` | React Hooks rules |
|
|
47
45
|
|
|
46
|
+
### CLI
|
|
47
|
+
|
|
48
|
+
| File | Description |
|
|
49
|
+
|------|-------------|
|
|
50
|
+
| `bin/init.js` | CLI script for initializing eslint.config.js |
|
|
51
|
+
| `templates/react.js` | Template for React projects |
|
|
52
|
+
| `templates/nextjs.js` | Template for Next.js projects |
|
|
53
|
+
| `templates/typescript.js` | Template for pure TypeScript projects |
|
|
54
|
+
|
|
48
55
|
### Utility Files for Other Projects
|
|
49
56
|
|
|
50
57
|
| File | Description |
|
|
@@ -70,18 +77,18 @@ npm run publish:beta # Publish beta version
|
|
|
70
77
|
Each module exports an array of configurations that can be spread:
|
|
71
78
|
|
|
72
79
|
```javascript
|
|
73
|
-
// Typical
|
|
80
|
+
// Typical React setup
|
|
74
81
|
import {
|
|
75
82
|
typescriptConfig,
|
|
76
|
-
|
|
83
|
+
reactConfig,
|
|
77
84
|
importsConfig,
|
|
78
85
|
prettierConfig
|
|
79
86
|
} from '@viclafouch/eslint-config-viclafouch'
|
|
80
87
|
|
|
81
88
|
export default [
|
|
82
|
-
{ ignores: ['**/node_modules/**'
|
|
89
|
+
{ ignores: ['**/node_modules/**'] },
|
|
83
90
|
...typescriptConfig,
|
|
84
|
-
...
|
|
91
|
+
...reactConfig,
|
|
85
92
|
...importsConfig,
|
|
86
93
|
...prettierConfig
|
|
87
94
|
]
|
|
@@ -93,8 +100,7 @@ export default [
|
|
|
93
100
|
2. **nextConfig** → Next.js rules (includes React + Hooks + a11y)
|
|
94
101
|
3. **reactConfig** + **hooksConfig** → For React without Next.js
|
|
95
102
|
4. **importsConfig** → Import sorting
|
|
96
|
-
5. **
|
|
97
|
-
6. **prettierConfig** → Formatting (must be last)
|
|
103
|
+
5. **prettierConfig** → Formatting (must be last)
|
|
98
104
|
|
|
99
105
|
## Integrated Plugins
|
|
100
106
|
|
|
@@ -106,7 +112,6 @@ export default [
|
|
|
106
112
|
- `eslint-plugin-promise` - Promise handling
|
|
107
113
|
- `eslint-plugin-unicorn` - Best practices
|
|
108
114
|
- `eslint-plugin-prettier` - Code formatting
|
|
109
|
-
- `eslint-plugin-better-tailwindcss` - Tailwind v4
|
|
110
115
|
- `@next/eslint-plugin-next` - Next.js specific
|
|
111
116
|
|
|
112
117
|
## Peer Dependencies
|
package/README.md
CHANGED
|
@@ -16,12 +16,11 @@ npx @viclafouch/eslint-config-viclafouch
|
|
|
16
16
|
|
|
17
17
|
This will prompt you to select your stack and create the `eslint.config.js` file automatically.
|
|
18
18
|
|
|
19
|
-
## Manual Setup (React
|
|
19
|
+
## Manual Setup (React)
|
|
20
20
|
|
|
21
21
|
```js
|
|
22
22
|
// eslint.config.js
|
|
23
23
|
import {
|
|
24
|
-
betterTailwindcssConfig,
|
|
25
24
|
importsConfig,
|
|
26
25
|
prettierConfig,
|
|
27
26
|
reactConfig,
|
|
@@ -42,14 +41,13 @@ export default [
|
|
|
42
41
|
...typescriptConfig,
|
|
43
42
|
...reactConfig,
|
|
44
43
|
...importsConfig,
|
|
45
|
-
...betterTailwindcssConfig({ entryPoint: 'src/styles.css' }),
|
|
46
44
|
...prettierConfig
|
|
47
45
|
]
|
|
48
46
|
```
|
|
49
47
|
|
|
50
48
|
## Stack Examples
|
|
51
49
|
|
|
52
|
-
### React + Vite
|
|
50
|
+
### React + Vite
|
|
53
51
|
|
|
54
52
|
```js
|
|
55
53
|
// eslint.config.js
|
|
@@ -100,7 +98,6 @@ export default [
|
|
|
100
98
|
```js
|
|
101
99
|
// eslint.config.js
|
|
102
100
|
import {
|
|
103
|
-
betterTailwindcssConfig,
|
|
104
101
|
importsConfig,
|
|
105
102
|
nextConfig,
|
|
106
103
|
prettierConfig,
|
|
@@ -115,7 +112,6 @@ export default [
|
|
|
115
112
|
...typescriptConfig,
|
|
116
113
|
...nextConfig,
|
|
117
114
|
...importsConfig,
|
|
118
|
-
...betterTailwindcssConfig({ entryPoint: 'src/app/globals.css' }),
|
|
119
115
|
...prettierConfig
|
|
120
116
|
]
|
|
121
117
|
```
|
|
@@ -129,7 +125,6 @@ export default [
|
|
|
129
125
|
| `hooksConfig` | React Hooks |
|
|
130
126
|
| `nextConfig` | Next.js (includes React + Hooks + a11y) |
|
|
131
127
|
| `importsConfig` | Automatic import sorting |
|
|
132
|
-
| `betterTailwindcssConfig({ entryPoint })` | Tailwind CSS v4 |
|
|
133
128
|
| `prettierConfig` | Prettier (always last) |
|
|
134
129
|
|
|
135
130
|
## TypeScript
|
|
@@ -187,5 +182,4 @@ import '@viclafouch/eslint-config-viclafouch/reset.d'
|
|
|
187
182
|
2. `typescriptConfig` (base)
|
|
188
183
|
3. `reactConfig` / `nextConfig` / `hooksConfig`
|
|
189
184
|
4. `importsConfig`
|
|
190
|
-
5. `
|
|
191
|
-
6. `prettierConfig` (always last)
|
|
185
|
+
5. `prettierConfig` (always last)
|
package/bin/init.js
CHANGED
|
@@ -10,8 +10,8 @@ const filename = fileURLToPath(import.meta.url)
|
|
|
10
10
|
const directory = dirname(filename)
|
|
11
11
|
|
|
12
12
|
const TEMPLATES = {
|
|
13
|
-
1: { name: 'React
|
|
14
|
-
2: { name: 'Next.js
|
|
13
|
+
1: { name: 'React', file: 'react.js' },
|
|
14
|
+
2: { name: 'Next.js', file: 'nextjs.js' },
|
|
15
15
|
3: { name: 'Pure TypeScript', file: 'typescript.js' }
|
|
16
16
|
}
|
|
17
17
|
|
package/index.d.ts
CHANGED
|
@@ -6,12 +6,3 @@ export declare const nextConfig: Linter.Config[]
|
|
|
6
6
|
export declare const prettierConfig: Linter.Config[]
|
|
7
7
|
export declare const hooksConfig: Linter.Config[]
|
|
8
8
|
export declare const importsConfig: Linter.Config[]
|
|
9
|
-
|
|
10
|
-
export interface BetterTailwindcssOptions {
|
|
11
|
-
/** Path to the CSS entry file (Tailwind v4) */
|
|
12
|
-
entryPoint: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export declare function betterTailwindcssConfig(
|
|
16
|
-
options: BetterTailwindcssOptions
|
|
17
|
-
): Linter.Config[]
|
package/index.mjs
CHANGED
package/package.json
CHANGED
package/rules/react.mjs
CHANGED
|
@@ -376,6 +376,10 @@ export default [
|
|
|
376
376
|
}
|
|
377
377
|
],
|
|
378
378
|
|
|
379
|
+
// Require or prevent a new line after jsx elements and expressions
|
|
380
|
+
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-newline.md
|
|
381
|
+
'react/jsx-newline': ['error', { prevent: true }],
|
|
382
|
+
|
|
379
383
|
// https://github.com/jsx-eslint/eslint-plugin-react/blob/66b58dd4864678eb869a7bf434c72ff7ac530eb1/docs/rules/no-object-type-as-default-prop.md
|
|
380
384
|
'react/no-object-type-as-default-prop': 'error',
|
|
381
385
|
|
|
@@ -395,7 +399,35 @@ export default [
|
|
|
395
399
|
|
|
396
400
|
// Disable spreading props in components more than once
|
|
397
401
|
// https://github.com/jsx-eslint/eslint-plugin-react/blob/v7.35.0/docs/rules/jsx-props-no-spread-multi.md
|
|
398
|
-
'react/jsx-props-no-spread-multi': 'off'
|
|
402
|
+
'react/jsx-props-no-spread-multi': 'off',
|
|
403
|
+
|
|
404
|
+
// Disallow destructured imports from React and ReactDOM - use React.useState, React.useEffect, React.ReactNode, etc.
|
|
405
|
+
// Disallow useMemo and useCallback unless proven performance problem
|
|
406
|
+
// https://eslint.org/docs/latest/rules/no-restricted-syntax
|
|
407
|
+
'no-restricted-syntax': [
|
|
408
|
+
'error',
|
|
409
|
+
{
|
|
410
|
+
selector: 'ImportDeclaration[source.value="react"] ImportSpecifier',
|
|
411
|
+
message:
|
|
412
|
+
'Use React.useState, React.ReactNode, etc. instead of destructuring React imports.'
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
selector:
|
|
416
|
+
'ImportDeclaration[source.value="react-dom"] ImportSpecifier',
|
|
417
|
+
message:
|
|
418
|
+
'Use ReactDOM.createRoot, etc. instead of destructuring ReactDOM imports.'
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
selector: 'CallExpression[callee.property.name="useMemo"]',
|
|
422
|
+
message:
|
|
423
|
+
'Avoid React.useMemo unless you have a proven performance problem.'
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
selector: 'CallExpression[callee.property.name="useCallback"]',
|
|
427
|
+
message:
|
|
428
|
+
'Avoid React.useCallback unless you have a proven performance problem.'
|
|
429
|
+
}
|
|
430
|
+
]
|
|
399
431
|
}
|
|
400
432
|
},
|
|
401
433
|
{
|
package/rules/typescript.mjs
CHANGED
|
@@ -97,6 +97,25 @@ export default defineConfig(
|
|
|
97
97
|
// https://eslint.org/docs/rules/complexity
|
|
98
98
|
complexity: ['error', 20],
|
|
99
99
|
|
|
100
|
+
// Disallow nested ternary expressions
|
|
101
|
+
// https://eslint.org/docs/latest/rules/no-nested-ternary
|
|
102
|
+
'no-nested-ternary': 'error',
|
|
103
|
+
|
|
104
|
+
// Enforce a maximum number of parameters in function definitions
|
|
105
|
+
// https://eslint.org/docs/latest/rules/max-params
|
|
106
|
+
'max-params': ['error', { max: 3 }],
|
|
107
|
+
|
|
108
|
+
// Enforce a maximum depth of nested blocks
|
|
109
|
+
// https://eslint.org/docs/latest/rules/max-depth
|
|
110
|
+
'max-depth': ['error', { max: 3 }],
|
|
111
|
+
|
|
112
|
+
// Enforce a maximum number of lines per function
|
|
113
|
+
// https://eslint.org/docs/latest/rules/max-lines-per-function
|
|
114
|
+
'max-lines-per-function': [
|
|
115
|
+
'error',
|
|
116
|
+
{ max: 250, skipBlankLines: true, skipComments: true }
|
|
117
|
+
],
|
|
118
|
+
|
|
100
119
|
// Enforce that class methods use "this"
|
|
101
120
|
// https://eslint.org/docs/rules/class-methods-use-this
|
|
102
121
|
'class-methods-use-this': [
|
|
@@ -758,6 +777,10 @@ export default defineConfig(
|
|
|
758
777
|
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-reverse.md
|
|
759
778
|
'unicorn/no-array-reverse': 'error',
|
|
760
779
|
|
|
780
|
+
// Prefer Array#toSorted() over Array#sort() to avoid mutation
|
|
781
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-sort.md
|
|
782
|
+
'unicorn/no-array-sort': 'error',
|
|
783
|
+
|
|
761
784
|
// Require using new when throwing an error
|
|
762
785
|
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/throw-new-error.md
|
|
763
786
|
'unicorn/throw-new-error': 'error',
|
|
@@ -822,6 +845,10 @@ export default defineConfig(
|
|
|
822
845
|
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-spread.md
|
|
823
846
|
'unicorn/prefer-spread': 'off',
|
|
824
847
|
|
|
848
|
+
// Prefer ternary expressions over simple if-else statements (DISABLED - prefer if-else for clarity)
|
|
849
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-ternary.md
|
|
850
|
+
'unicorn/prefer-ternary': 'off',
|
|
851
|
+
|
|
825
852
|
// Prefer omitting catch binding when unused
|
|
826
853
|
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-optional-catch-binding.md
|
|
827
854
|
'unicorn/prefer-optional-catch-binding': 'off',
|
|
@@ -957,9 +984,17 @@ export default defineConfig(
|
|
|
957
984
|
'no-return-await': 'off',
|
|
958
985
|
'@typescript-eslint/return-await': ['error', 'in-try-catch'],
|
|
959
986
|
|
|
960
|
-
//
|
|
987
|
+
// Disallow @ts-<directive> comments or require descriptions after directives
|
|
961
988
|
// https://typescript-eslint.io/rules/ban-ts-comment
|
|
962
|
-
'@typescript-eslint/ban-ts-comment':
|
|
989
|
+
'@typescript-eslint/ban-ts-comment': [
|
|
990
|
+
'error',
|
|
991
|
+
{
|
|
992
|
+
'ts-expect-error': 'allow-with-description',
|
|
993
|
+
'ts-ignore': 'allow-with-description',
|
|
994
|
+
'ts-nocheck': 'allow-with-description',
|
|
995
|
+
'ts-check': false
|
|
996
|
+
}
|
|
997
|
+
],
|
|
963
998
|
|
|
964
999
|
// Naming convention for type parameters
|
|
965
1000
|
// https://typescript-eslint.io/rules/naming-convention
|
|
@@ -981,6 +1016,25 @@ export default defineConfig(
|
|
|
981
1016
|
// https://typescript-eslint.io/rules/array-type
|
|
982
1017
|
'@typescript-eslint/array-type': 'error',
|
|
983
1018
|
|
|
1019
|
+
// Enforce type definitions to consistently use type instead of interface
|
|
1020
|
+
// https://typescript-eslint.io/rules/consistent-type-definitions
|
|
1021
|
+
'@typescript-eslint/consistent-type-definitions': ['error', 'type'],
|
|
1022
|
+
|
|
1023
|
+
// Disallow the any type
|
|
1024
|
+
// https://typescript-eslint.io/rules/no-explicit-any
|
|
1025
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
|
1026
|
+
|
|
1027
|
+
// Require Promise-like statements to be handled appropriately
|
|
1028
|
+
// https://typescript-eslint.io/rules/no-floating-promises
|
|
1029
|
+
'@typescript-eslint/no-floating-promises': [
|
|
1030
|
+
'error',
|
|
1031
|
+
{ ignoreVoid: true }
|
|
1032
|
+
],
|
|
1033
|
+
|
|
1034
|
+
// Disallow explicit return type annotations on functions (trust inference)
|
|
1035
|
+
// https://typescript-eslint.io/rules/explicit-function-return-type
|
|
1036
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
1037
|
+
|
|
984
1038
|
// Forbid delete array, use splice for example
|
|
985
1039
|
// https://typescript-eslint.io/rules/no-array-delete
|
|
986
1040
|
'@typescript-eslint/no-array-delete': 'error',
|
package/templates/nextjs.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
betterTailwindcssConfig,
|
|
3
2
|
importsConfig,
|
|
4
3
|
nextConfig,
|
|
5
4
|
prettierConfig,
|
|
@@ -14,6 +13,5 @@ export default [
|
|
|
14
13
|
...typescriptConfig,
|
|
15
14
|
...nextConfig,
|
|
16
15
|
...importsConfig,
|
|
17
|
-
...betterTailwindcssConfig({ entryPoint: 'src/app/globals.css' }),
|
|
18
16
|
...prettierConfig
|
|
19
17
|
]
|
package/templates/react.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
betterTailwindcssConfig,
|
|
3
2
|
importsConfig,
|
|
4
3
|
prettierConfig,
|
|
5
4
|
reactConfig,
|
|
@@ -21,6 +20,5 @@ export default [
|
|
|
21
20
|
...typescriptConfig,
|
|
22
21
|
...reactConfig,
|
|
23
22
|
...importsConfig,
|
|
24
|
-
...betterTailwindcssConfig({ entryPoint: 'src/styles.css' }),
|
|
25
23
|
...prettierConfig
|
|
26
24
|
]
|
package/better-tailwindcss.mjs
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import betterTailwindcss from 'eslint-plugin-better-tailwindcss'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {Object} BetterTailwindcssOptions
|
|
5
|
-
* @property {string} entryPoint - Path to the CSS entry file (Tailwind v4)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Creates ESLint flat config for eslint-plugin-better-tailwindcss (Tailwind v4)
|
|
10
|
-
* @param {BetterTailwindcssOptions} options
|
|
11
|
-
* @returns {import("eslint").Linter.Config[]}
|
|
12
|
-
*/
|
|
13
|
-
export default function betterTailwindcssConfig({ entryPoint }) {
|
|
14
|
-
const recommendedRules = betterTailwindcss.configs?.recommended?.rules ?? {}
|
|
15
|
-
|
|
16
|
-
return [
|
|
17
|
-
{
|
|
18
|
-
files: ['**/*.{js,jsx,ts,tsx}'],
|
|
19
|
-
plugins: {
|
|
20
|
-
'better-tailwindcss': betterTailwindcss
|
|
21
|
-
},
|
|
22
|
-
settings: {
|
|
23
|
-
'better-tailwindcss': {
|
|
24
|
-
entryPoint
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
rules: {
|
|
28
|
-
...recommendedRules
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
]
|
|
32
|
-
}
|