@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.
@@ -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 Next.js setup
80
+ // Typical React setup
74
81
  import {
75
82
  typescriptConfig,
76
- nextConfig,
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/**', '**/.next/**'] },
89
+ { ignores: ['**/node_modules/**'] },
83
90
  ...typescriptConfig,
84
- ...nextConfig,
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. **betterTailwindcssConfig({ entryPoint })** → Tailwind CSS v4
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 + Tailwind)
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 (without Tailwind)
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. `betterTailwindcssConfig`
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 + Tailwind', file: 'react.js' },
14
- 2: { name: 'Next.js + Tailwind', file: 'nextjs.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
@@ -1,4 +1,3 @@
1
- export { default as betterTailwindcssConfig } from './better-tailwindcss.mjs'
2
1
  export { default as hooksConfig } from './hooks.mjs'
3
2
  export { default as importsConfig } from './imports.mjs'
4
3
  export { default as nextConfig } from './next.mjs'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viclafouch/eslint-config-viclafouch",
3
- "version": "4.22.1-beta.5",
3
+ "version": "4.22.1-beta.7",
4
4
  "description": "ESLint and Prettier Config from Victor de la Fouchardiere",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",
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
  {
@@ -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
- // Accept banning ts lines
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': 'off',
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',
@@ -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
  ]
@@ -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
  ]
@@ -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
- }