@dendavidov/eslint-config-react 1.1.45 → 2.0.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/README.md CHANGED
@@ -16,21 +16,33 @@ npm i -D @dendavidov/eslint-config-react
16
16
 
17
17
  ## Usage
18
18
 
19
- Add .eslintrc.json in the root of your project
20
- ```json
21
- {
22
- "extends": "@dendavidov/eslint-config-react"
23
- }
19
+ Create `eslint.config.js` in the root of your project:
20
+ ```javascript
21
+ import config from '@dendavidov/eslint-config-react';
22
+
23
+ export default config;
24
24
  ```
25
- Add script to package.json -> scripts:
25
+
26
+ Or extend with your own rules:
27
+ ```javascript
28
+ import config from '@dendavidov/eslint-config-react';
29
+
30
+ export default [
31
+ ...config,
32
+ {
33
+ rules: {
34
+ // Your custom rules
35
+ }
36
+ }
37
+ ];
26
38
  ```
39
+
40
+ Add script to package.json:
41
+ ```json
27
42
  {
28
- ...
29
43
  "scripts": {
30
- ...
31
- "lint": "eslint './src/**/*.{ts,tsx}'"
32
- },
33
- ...
44
+ "lint": "eslint './src/**/*.{ts,tsx,js,jsx}'"
45
+ }
34
46
  }
35
47
  ```
36
48
 
package/package.json CHANGED
@@ -1,15 +1,12 @@
1
1
  {
2
2
  "name": "@dendavidov/eslint-config-react",
3
- "version": "1.1.45",
4
- "description": "eslint config",
3
+ "version": "2.0.1",
4
+ "description": "Shareable ESLint config for React + TypeScript (ESLint 9+)",
5
+ "type": "module",
5
6
  "main": "src/index.js",
7
+ "types": "src/index.d.ts",
6
8
  "license": "MIT",
7
- "scripts": {
8
- "test": "jest --watchAll=false",
9
- "release": "npx semantic-release",
10
- "prepare": "npx husky install"
11
- },
12
- "author": "Denis Davydov mail@dendavidov.com",
9
+ "author": "Denis Davydov <mail@dendavidov.com>",
13
10
  "repository": {
14
11
  "type": "git",
15
12
  "url": "git@github.com:dendavidov/eslint-config-react.git"
@@ -24,27 +21,48 @@
24
21
  "files": [
25
22
  "LICENSE",
26
23
  "README.md",
27
- "src/index.js"
24
+ "src/index.js",
25
+ "src/index.d.ts"
28
26
  ],
29
- "devDependencies": {
30
- "@commitlint/cli": "^19.3.0",
31
- "@commitlint/config-conventional": "^19.2.2",
32
- "@semantic-release/git": "^10.0.1",
33
- "conventional-changelog-conventionalcommits": "^7.0.2",
34
- "husky": "^9.0.11",
35
- "jest": "^29.5.0",
36
- "prettier": "^3.0.0"
27
+ "scripts": {
28
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest --watchAll=false",
29
+ "format": "prettier --write .",
30
+ "format:check": "prettier --check ./src",
31
+ "release": "npx semantic-release",
32
+ "prepare": "npx husky install"
37
33
  },
38
34
  "dependencies": {
39
- "@typescript-eslint/eslint-plugin": "^7.8.0",
40
- "@typescript-eslint/parser": "^7.8.0",
41
- "eslint": "^8.37.0",
42
- "eslint-config-prettier": "^9.0.0",
43
- "eslint-import-resolver-typescript": "^3.5.5",
44
- "eslint-plugin-import": "^2.27.5",
45
- "eslint-plugin-jest": "^28.3.0",
46
- "eslint-plugin-jsx-a11y": "^6.7.1",
47
- "eslint-plugin-react": "^7.32.2",
48
- "eslint-plugin-testing-library": "^6.0.1"
35
+ "@eslint/js": "^9.31.0"
36
+ },
37
+ "peerDependencies": {
38
+ "@typescript-eslint/eslint-plugin": "^8.36.0",
39
+ "@typescript-eslint/parser": "^8.36.0",
40
+ "eslint": "^9.0.0",
41
+ "eslint-config-prettier": "^10.1.5",
42
+ "eslint-import-resolver-typescript": "^4.4.4",
43
+ "eslint-plugin-import": "^2.32.0",
44
+ "eslint-plugin-jest": "^29.0.1",
45
+ "eslint-plugin-jsx-a11y": "^6.10.2",
46
+ "eslint-plugin-react": "^7.37.5",
47
+ "eslint-plugin-testing-library": "^7.5.4"
48
+ },
49
+ "devDependencies": {
50
+ "@commitlint/cli": "^19.8.1",
51
+ "@commitlint/config-conventional": "^19.8.1",
52
+ "@semantic-release/git": "^10.0.1",
53
+ "@typescript-eslint/eslint-plugin": "^8.36.0",
54
+ "@typescript-eslint/parser": "^8.36.0",
55
+ "conventional-changelog-conventionalcommits": "^9.1.0",
56
+ "eslint": "^9.31.0",
57
+ "eslint-config-prettier": "^10.1.5",
58
+ "eslint-import-resolver-typescript": "^4.4.4",
59
+ "eslint-plugin-import": "^2.32.0",
60
+ "eslint-plugin-jest": "^29.0.1",
61
+ "eslint-plugin-jsx-a11y": "^6.10.2",
62
+ "eslint-plugin-react": "^7.37.5",
63
+ "eslint-plugin-testing-library": "^7.5.4",
64
+ "husky": "^9.1.7",
65
+ "jest": "^30.0.4",
66
+ "prettier": "^3.6.2"
49
67
  }
50
68
  }
package/src/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { Linter } from 'eslint';
2
+
3
+ declare const config: Linter.FlatConfig[];
4
+
5
+ export default config;
package/src/index.js CHANGED
@@ -1,66 +1,323 @@
1
- module.exports = {
2
- extends: [
3
- // By extending from a plugin config, we can get recommended rules without having to add them manually.
4
- 'eslint:recommended',
5
- 'plugin:react/recommended',
6
- 'plugin:import/recommended',
7
- 'plugin:jsx-a11y/recommended',
8
- 'plugin:@typescript-eslint/recommended',
9
- 'plugin:@typescript-eslint/recommended-requiring-type-checking',
10
- 'plugin:@typescript-eslint/strict',
11
- // This disables the formatting rules in ESLint that Prettier is going to be responsible for handling.
12
- // Make sure it's always the last config, so it gets the chance to override other configs.
13
- 'eslint-config-prettier',
14
- ],
15
- "parserOptions": {
16
- "project": "./tsconfig.json",
17
- "ecmaVersion": 12,
18
- "sourceType": "module"
1
+ import js from '@eslint/js';
2
+ import reactPlugin from 'eslint-plugin-react';
3
+ import importPlugin from 'eslint-plugin-import';
4
+ import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
5
+ import tsPlugin from '@typescript-eslint/eslint-plugin';
6
+ import tsParser from '@typescript-eslint/parser';
7
+ import jestPlugin from 'eslint-plugin-jest';
8
+ import testingLibraryPlugin from 'eslint-plugin-testing-library';
9
+ import prettierConfig from 'eslint-config-prettier';
10
+
11
+ export default [
12
+ // core ESLint recommended
13
+ js.configs.recommended,
14
+
15
+ // React configuration
16
+ {
17
+ files: ['**/*.{js,jsx,ts,tsx}'],
18
+ languageOptions: {
19
+ ecmaVersion: 2020,
20
+ sourceType: 'module',
21
+ parserOptions: {
22
+ ecmaFeatures: {
23
+ jsx: true,
24
+ },
25
+ },
26
+ globals: {
27
+ // Browser globals
28
+ window: 'readonly',
29
+ document: 'readonly',
30
+ console: 'readonly',
31
+ localStorage: 'readonly',
32
+ sessionStorage: 'readonly',
33
+ fetch: 'readonly',
34
+ setTimeout: 'readonly',
35
+ clearTimeout: 'readonly',
36
+ setInterval: 'readonly',
37
+ clearInterval: 'readonly',
38
+ alert: 'readonly',
39
+ confirm: 'readonly',
40
+ prompt: 'readonly',
41
+ // React globals
42
+ React: 'readonly',
43
+ JSX: 'readonly',
44
+ },
45
+ },
46
+ plugins: {
47
+ react: reactPlugin,
48
+ },
49
+ rules: {
50
+ ...reactPlugin.configs.recommended.rules,
51
+ 'react/react-in-jsx-scope': 'off',
52
+ },
53
+ settings: {
54
+ react: { version: 'detect' },
55
+ },
56
+ },
57
+
58
+ // Import configuration
59
+ {
60
+ files: ['**/*.{js,jsx,ts,tsx}'],
61
+ languageOptions: {
62
+ ecmaVersion: 2020,
63
+ sourceType: 'module',
64
+ parserOptions: {
65
+ ecmaFeatures: {
66
+ jsx: true,
67
+ },
68
+ },
69
+ globals: {
70
+ // Browser globals
71
+ window: 'readonly',
72
+ document: 'readonly',
73
+ console: 'readonly',
74
+ localStorage: 'readonly',
75
+ sessionStorage: 'readonly',
76
+ fetch: 'readonly',
77
+ setTimeout: 'readonly',
78
+ clearTimeout: 'readonly',
79
+ setInterval: 'readonly',
80
+ clearInterval: 'readonly',
81
+ // React globals
82
+ React: 'readonly',
83
+ JSX: 'readonly',
84
+ },
85
+ },
86
+ plugins: {
87
+ import: importPlugin,
88
+ },
89
+ rules: {
90
+ ...importPlugin.configs.recommended.rules,
91
+ 'import/no-unresolved': [2, { ignore: ['react-dom/client'] }],
92
+ },
93
+ settings: {
94
+ 'import/resolver': {
95
+ node: { paths: ['src'], extensions: ['.ts', '.tsx'] },
96
+ typescript: {},
97
+ },
98
+ },
99
+ },
100
+
101
+ // JSX A11y configuration
102
+ {
103
+ files: ['**/*.{js,jsx,ts,tsx}'],
104
+ languageOptions: {
105
+ ecmaVersion: 2020,
106
+ sourceType: 'module',
107
+ parserOptions: {
108
+ ecmaFeatures: {
109
+ jsx: true,
110
+ },
111
+ },
112
+ globals: {
113
+ // Browser globals
114
+ window: 'readonly',
115
+ document: 'readonly',
116
+ console: 'readonly',
117
+ localStorage: 'readonly',
118
+ sessionStorage: 'readonly',
119
+ fetch: 'readonly',
120
+ setTimeout: 'readonly',
121
+ clearTimeout: 'readonly',
122
+ setInterval: 'readonly',
123
+ clearInterval: 'readonly',
124
+ // React globals
125
+ React: 'readonly',
126
+ JSX: 'readonly',
127
+ },
128
+ },
129
+ plugins: {
130
+ 'jsx-a11y': jsxA11yPlugin,
131
+ },
132
+ rules: {
133
+ ...jsxA11yPlugin.configs.recommended.rules,
134
+ },
19
135
  },
20
- plugins: ['jest', 'testing-library', '@typescript-eslint'],
21
- settings: {
22
- react: {
23
- // Tells eslint-plugin-react to automatically detect the version of React to use.
24
- version: 'detect',
25
- },
26
- // Tells eslint how to resolve imports
27
- 'import/resolver': {
28
- node: {
29
- paths: ['src'],
30
- extensions: ['.ts', '.tsx'],
136
+
137
+ // TypeScript configuration
138
+ {
139
+ files: ['**/*.{ts,tsx}'],
140
+ languageOptions: {
141
+ parser: tsParser,
142
+ parserOptions: {
143
+ ecmaVersion: 2020,
144
+ sourceType: 'module',
145
+ project: './tsconfig.json',
146
+ ecmaFeatures: {
147
+ jsx: true,
148
+ },
149
+ },
150
+ globals: {
151
+ // Browser globals
152
+ window: 'readonly',
153
+ document: 'readonly',
154
+ console: 'readonly',
155
+ localStorage: 'readonly',
156
+ sessionStorage: 'readonly',
157
+ fetch: 'readonly',
158
+ setTimeout: 'readonly',
159
+ clearTimeout: 'readonly',
160
+ setInterval: 'readonly',
161
+ clearInterval: 'readonly',
162
+ alert: 'readonly',
163
+ confirm: 'readonly',
164
+ prompt: 'readonly',
165
+ // React globals
166
+ React: 'readonly',
167
+ JSX: 'readonly',
31
168
  },
32
- typescript: {},
169
+ },
170
+ plugins: {
171
+ '@typescript-eslint': tsPlugin,
172
+ },
173
+ rules: {
174
+ ...tsPlugin.configs.recommended.rules,
175
+ ...tsPlugin.configs['recommended-type-checked'].rules,
176
+ ...tsPlugin.configs.strict.rules,
33
177
  },
34
178
  },
35
- overrides: [
36
- {
37
- files: ['**/__tests__/**/*', '**/*.{spec,test}.*'],
38
- env: {
39
- 'jest/globals': true,
179
+
180
+ // disable formatting rules in ESLint so Prettier can run unopposed
181
+ prettierConfig,
182
+
183
+ // Test files configuration
184
+ {
185
+ files: ['**/__tests__/**/*', '**/*.{spec,test}.*', '**/jest.setup.*'],
186
+ languageOptions: {
187
+ ecmaVersion: 2020,
188
+ sourceType: 'module',
189
+ parserOptions: {
190
+ ecmaFeatures: {
191
+ jsx: true,
192
+ },
193
+ },
194
+ globals: {
195
+ // Jest globals
196
+ afterAll: 'readonly',
197
+ afterEach: 'readonly',
198
+ beforeAll: 'readonly',
199
+ beforeEach: 'readonly',
200
+ describe: 'readonly',
201
+ expect: 'readonly',
202
+ fit: 'readonly',
203
+ it: 'readonly',
204
+ jest: 'readonly',
205
+ test: 'readonly',
206
+ xdescribe: 'readonly',
207
+ xit: 'readonly',
208
+ xtest: 'readonly',
209
+ // Node.js globals for setup files
210
+ global: 'writable',
211
+ // Browser globals (for JSDOM environment)
212
+ window: 'readonly',
213
+ document: 'readonly',
214
+ console: 'readonly',
215
+ localStorage: 'readonly',
216
+ sessionStorage: 'readonly',
217
+ fetch: 'readonly',
218
+ setTimeout: 'readonly',
219
+ clearTimeout: 'readonly',
220
+ setInterval: 'readonly',
221
+ clearInterval: 'readonly',
222
+ // React globals
223
+ React: 'readonly',
224
+ JSX: 'readonly',
40
225
  },
41
- // A subset of the recommended rules:
42
- rules: {
43
- // https://github.com/jest-community/eslint-plugin-jest
44
- 'jest/no-conditional-expect': 'error',
45
- 'jest/no-identical-title': 'error',
46
- 'jest/no-interpolation-in-snapshots': 'error',
47
- 'jest/no-jasmine-globals': 'error',
48
- 'jest/no-mocks-import': 'error',
49
- 'jest/valid-describe-callback': 'error',
50
- 'jest/valid-expect': 'error',
51
- 'jest/valid-expect-in-promise': 'error',
52
- 'jest/valid-title': 'warn',
226
+ },
227
+ plugins: {
228
+ jest: jestPlugin,
229
+ 'testing-library': testingLibraryPlugin,
230
+ },
231
+ rules: {
232
+ ...jestPlugin.configs.recommended.rules,
233
+ 'jest/no-conditional-expect': 'error',
234
+ 'jest/no-identical-title': 'error',
235
+ 'jest/no-interpolation-in-snapshots': 'error',
236
+ 'jest/no-jasmine-globals': 'error',
237
+ 'jest/no-mocks-import': 'error',
238
+ 'jest/valid-describe-callback': 'error',
239
+ 'jest/valid-expect': 'error',
240
+ 'jest/valid-expect-in-promise': 'error',
241
+ 'jest/valid-title': 'warn',
242
+ 'testing-library/await-async-queries': 'error',
243
+ 'testing-library/await-async-utils': 'error',
244
+ 'testing-library/no-dom-import': ['error', 'react'],
245
+ 'testing-library/no-wait-for-snapshot': 'error',
246
+ },
247
+ },
53
248
 
54
- // https://github.com/testing-library/eslint-plugin-testing-library
55
- 'testing-library/await-async-queries': 'error',
56
- 'testing-library/await-async-utils': 'error',
57
- 'testing-library/no-dom-import': ['error', 'react'],
58
- 'testing-library/no-wait-for-snapshot': 'error',
249
+ // TypeScript test files configuration
250
+ {
251
+ files: ['**/__tests__/**/*.{ts,tsx}', '**/*.{spec,test}.{ts,tsx}', '**/jest.setup.{ts,tsx}'],
252
+ languageOptions: {
253
+ parser: tsParser,
254
+ parserOptions: {
255
+ ecmaVersion: 2020,
256
+ sourceType: 'module',
257
+ project: './tsconfig.json',
258
+ ecmaFeatures: {
259
+ jsx: true,
260
+ },
261
+ },
262
+ globals: {
263
+ // Jest globals
264
+ afterAll: 'readonly',
265
+ afterEach: 'readonly',
266
+ beforeAll: 'readonly',
267
+ beforeEach: 'readonly',
268
+ describe: 'readonly',
269
+ expect: 'readonly',
270
+ fit: 'readonly',
271
+ it: 'readonly',
272
+ jest: 'readonly',
273
+ test: 'readonly',
274
+ xdescribe: 'readonly',
275
+ xit: 'readonly',
276
+ xtest: 'readonly',
277
+ // Node.js globals for setup files
278
+ global: 'writable',
279
+ // Browser globals (for JSDOM environment)
280
+ window: 'readonly',
281
+ document: 'readonly',
282
+ console: 'readonly',
283
+ localStorage: 'readonly',
284
+ sessionStorage: 'readonly',
285
+ fetch: 'readonly',
286
+ setTimeout: 'readonly',
287
+ clearTimeout: 'readonly',
288
+ setInterval: 'readonly',
289
+ clearInterval: 'readonly',
290
+ // React globals
291
+ React: 'readonly',
292
+ JSX: 'readonly',
59
293
  },
60
294
  },
61
- ],
62
- rules: {
63
- 'react/react-in-jsx-scope': 'off',
64
- 'import/no-unresolved': [2, { ignore: ['react-dom/client'] }],
295
+ plugins: {
296
+ '@typescript-eslint': tsPlugin,
297
+ jest: jestPlugin,
298
+ 'testing-library': testingLibraryPlugin,
299
+ },
300
+ rules: {
301
+ // TypeScript rules
302
+ ...tsPlugin.configs.recommended.rules,
303
+ ...tsPlugin.configs['recommended-type-checked'].rules,
304
+ ...tsPlugin.configs.strict.rules,
305
+ // Jest rules
306
+ ...jestPlugin.configs.recommended.rules,
307
+ 'jest/no-conditional-expect': 'error',
308
+ 'jest/no-identical-title': 'error',
309
+ 'jest/no-interpolation-in-snapshots': 'error',
310
+ 'jest/no-jasmine-globals': 'error',
311
+ 'jest/no-mocks-import': 'error',
312
+ 'jest/valid-describe-callback': 'error',
313
+ 'jest/valid-expect': 'error',
314
+ 'jest/valid-expect-in-promise': 'error',
315
+ 'jest/valid-title': 'warn',
316
+ // Testing Library rules
317
+ 'testing-library/await-async-queries': 'error',
318
+ 'testing-library/await-async-utils': 'error',
319
+ 'testing-library/no-dom-import': ['error', 'react'],
320
+ 'testing-library/no-wait-for-snapshot': 'error',
321
+ },
65
322
  },
66
- };
323
+ ];