zeno-config 4.0.2 → 5.0.0

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
@@ -42,8 +42,8 @@ Create an `eslint.config.js` file in your project root:
42
42
  import { defineZenoConfig } from 'zeno-config/eslint';
43
43
 
44
44
  export default defineZenoConfig({
45
+ reactIncludes: ['src'], // Directories/files with React code (enables React rules)
45
46
  ts: true, // Enable TypeScript support (default: false)
46
- react: true, // Enable React support (default: false)
47
47
  });
48
48
  ```
49
49
 
@@ -54,16 +54,16 @@ If you're using or preparing to adopt [React Compiler](https://react.dev/learn/r
54
54
  ```javascript
55
55
  import { defineZenoConfig } from 'zeno-config/eslint';
56
56
 
57
- // Preparing a codebase surface compiler violations as warnings
57
+ // Full enforcement — compiler rules as errors
58
58
  export default defineZenoConfig({
59
- react: true,
60
- reactCompiler: 'warn',
59
+ reactIncludes: ['src'],
60
+ reactCompiler: true,
61
61
  });
62
62
 
63
- // Full enforcement — compiler rules as errors
63
+ // Preparing a codebase surface compiler violations as warnings
64
64
  export default defineZenoConfig({
65
- react: true,
66
- reactCompiler: true,
65
+ reactIncludes: ['src'],
66
+ reactCompiler: 'warn',
67
67
  });
68
68
  ```
69
69
 
@@ -86,17 +86,16 @@ import { defineZenoConfig } from 'zeno-config/eslint';
86
86
 
87
87
  export default defineZenoConfig(
88
88
  {
89
- react: true,
90
89
  ts: true,
91
90
 
92
- // Additional directories to ignore (added to defaults: node_modules, dist, build, coverage)
93
- ignores: ['out', '.next'],
91
+ // Directories and files containing React code (enables React rules for all file types in these paths)
92
+ reactIncludes: ['src/client', 'src/components'],
94
93
 
95
- // If using .js extensions for React files, specify React directories
96
- reactDirs: ['src/client', 'src/components'],
94
+ // Directories and files containing Node.js code (scopes Node rules to these paths)
95
+ nodeIncludes: ['src/server', 'vite.config.ts', 'eslint.config.js'],
97
96
 
98
- // Ignore Node.js rules in specific directories (defaults to reactDirs)
99
- nodeIgnoreDirs: ['src/client'],
97
+ // Additional directories to ignore (added to defaults: node_modules, dist, build, coverage)
98
+ ignores: ['out', '.next'],
100
99
 
101
100
  // Patterns to ignore for import/no-unresolved rule
102
101
  ignoreExports: ['^@/'],
@@ -218,7 +217,7 @@ import {
218
217
  reactJsExtensions, // JSX-only extensions: .jsx, .mjsx, .cjsx
219
218
  reactJsExtensionsExtended, // JS + JSX extensions: .js, .mjs, .cjs, .jsx, .mjsx, .cjsx
220
219
  reactExtensions, // React extensions (JSX + TSX): .jsx, .mjsx, .cjsx, .tsx, .mtsx, .ctsx
221
- reactExtensionsExtended, // JS + JSX + TSX extensions: .js, .mjs, .cjs, .jsx, .mjsx, .cjsx, .tsx, .mtsx, .ctsx
220
+ reactExtensionsExtended, // All extensions for React directories: .js, .mjs, .cjs, .jsx, .mjsx, .cjsx, .ts, .cts, .mts, .tsx, .mtsx, .ctsx
222
221
  typescriptExtensions, // TypeScript extensions: .ts, .cts, .mts, .tsx, .mtsx, .ctsx
223
222
 
224
223
  // String versions for glob patterns (comma-separated)
@@ -227,7 +226,7 @@ import {
227
226
  reactJsExtensionsString, // ".jsx,.mjsx,.cjsx"
228
227
  reactJsExtensionsExtendedString, // ".js,.mjs,.cjs,.jsx,.mjsx,.cjsx"
229
228
  reactExtensionsString, // ".jsx,.mjsx,.cjsx,.tsx,.mtsx,.ctsx"
230
- reactExtensionsExtendedString, // ".js,.mjs,.cjs,.jsx,.mjsx,.cjsx,.tsx,.mtsx,.ctsx"
229
+ reactExtensionsExtendedString, // ".js,.mjs,.cjs,.jsx,.mjsx,.cjsx,.ts,.cts,.mts,.tsx,.mtsx,.ctsx"
231
230
  typescriptExtensionsString, // ".ts,.cts,.mts,.tsx,.mtsx,.ctsx"
232
231
  } from 'zeno-config/extensions';
233
232
  ```
@@ -236,13 +235,12 @@ import {
236
235
 
237
236
  | Option | Type | Default | Description |
238
237
  | --------------------------- | ----------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------- |
239
- | `react` | `boolean` | `false` | Enable React-specific rules |
240
- | `reactCompiler` | `boolean \| 'warn'` | `false` | Enable React Compiler rules. Set to `'warn'` to surface violations as warnings (for preparing a codebase), or `true` to enforce as errors |
238
+ | `reactIncludes` | `string[]` | `[]` | Directories and files containing React code. Setting this enables all React rules (hooks, JSX, a11y, etc.) for all file types in these paths. |
239
+ | `reactCompiler` | `boolean \| 'warn'` | `false` | Enable React Compiler rules. Set to `true` to enforce as errors, or `'warn'` to surface violations as warnings (recommended when preparing a codebase for React Compiler adoption). |
241
240
  | `ts` | `boolean` | `false` | Enable TypeScript-specific rules |
242
241
  | `performanceMode` | `boolean` | `false` | Disables expensive rules for better performance |
243
242
  | `ignores` | `string[]` | `[]` | Additional directories to ignore (added to defaults: node_modules, dist, build, coverage) |
244
- | `reactDirs` | `string[]` | `[]` | Directories containing React files (for projects using .js for both React and Node) |
245
- | `nodeIgnoreDirs` | `string[]` | `[]` | Directories to ignore for Node-specific rules (defaults to `reactDirs` if not set) |
243
+ | `nodeIncludes` | `string[]` | `[]` | Directories and files containing Node.js code. When set, Node-specific rules only apply to these paths. When not set but `reactIncludes` is set, `reactIncludes` directories are automatically excluded from Node rules. |
246
244
  | `ignoreExports` | `string[]` | `[]` | Export patterns to ignore for import/no-unresolved rule |
247
245
  | `additionalDevDependencies` | `string[]` | `[]` | Additional file patterns to allow dev dependencies in (for import/no-extraneous-dependencies) |
248
246
  | `extensionsIgnorePattern` | `object` | `{}` | Extension patterns to ignore for import/extensions rule |
@@ -261,9 +259,9 @@ const { configs, rules, extensions } = zenoInternals;
261
259
 
262
260
  export default [
263
261
  ...configs.getBase(),
264
- ...configs.getNode(),
265
- ...configs.getReact(),
266
- ...configs.getTypescript(),
262
+ ...configs.getNode({ includes: ['src/server'] }),
263
+ ...configs.getReact({ includes: ['src'] }),
264
+ ...configs.getTypescript({ react: true }),
267
265
  // Your custom configs
268
266
  ];
269
267
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zeno-config",
3
- "version": "4.0.2",
3
+ "version": "5.0.0",
4
4
  "description": "Preconfigured and opinionated ESLint, Prettier, and TypeScript setup",
5
5
  "author": "Rick Brenn <brenn.rick@gmail.com>",
6
6
  "license": "MIT",
@@ -68,13 +68,15 @@
68
68
  "@eslint/js": "9.39.2",
69
69
  "@stylistic/eslint-plugin": "5.10.0",
70
70
  "eslint-config-prettier": "10.1.8",
71
- "eslint-import-resolver-webpack": "^0.13.10",
71
+ "eslint-import-resolver-typescript": "4.4.4",
72
+ "eslint-import-resolver-webpack": "0.13.10",
72
73
  "eslint-plugin-import-x": "4.16.2",
73
74
  "eslint-plugin-jsx-a11y": "6.10.2",
74
75
  "eslint-plugin-n": "17.24.0",
75
76
  "eslint-plugin-prettier": "5.5.5",
76
77
  "eslint-plugin-react": "7.37.5",
77
78
  "eslint-plugin-react-hooks": "7.0.1",
79
+ "eslint-plugin-react-refresh": "0.5.2",
78
80
  "eslint-plugin-react-you-might-not-need-an-effect": "0.9.2",
79
81
  "eslint-plugin-unicorn": "63.0.0",
80
82
  "globals": "17.4.0",
@@ -9,21 +9,25 @@ interface BaseConfigOptions {
9
9
  extensionsIgnorePattern?: Record<string, string>;
10
10
  /** Path to webpack config for import resolver */
11
11
  webpackConfig?: string;
12
+ /** Enable TypeScript import resolution */
13
+ ts?: boolean;
12
14
  /** Disables expensive rules for performance */
13
15
  performanceMode?: boolean;
14
16
  }
15
17
 
16
18
  interface NodeConfigOptions {
17
- /** Additional directories to ignore for Node-specific rules */
19
+ /** Directories and files to apply Node-specific rules to. When set, Node rules only apply to these paths. */
20
+ includes?: string[];
21
+ /** Directories to exclude from Node-specific rules (used internally for auto-exclude) */
18
22
  ignoreDirs?: string[];
19
23
  }
20
24
 
21
25
  interface ReactConfigOptions {
22
- /** Directories containing React files (for projects using .js for both React and Node) */
23
- reactDirs?: string[];
26
+ /** Directories and files containing React code. Setting this enables React rules for all file types in these paths. */
27
+ includes?: string[];
24
28
  /** Extension patterns to ignore for import rules */
25
29
  extensionsIgnorePattern?: Record<string, string>;
26
- /** Enable React Compiler rules. Set to 'warn' for warnings or true for errors. */
30
+ /** Enable React Compiler rules. Set to true to enforce as errors, or 'warn' for warnings (recommended when preparing a codebase for React Compiler adoption). */
27
31
  reactCompiler?: boolean | 'warn';
28
32
  }
29
33
 
@@ -33,20 +37,18 @@ interface TypescriptConfigOptions {
33
37
  }
34
38
 
35
39
  interface DefineZenoConfigOptions {
36
- /** Enable React-specific rules */
37
- react?: boolean;
38
- /** Enable React Compiler rules. Set to 'warn' for warnings or true for errors. */
40
+ /** Directories and files containing React code. Setting this enables React rules for all file types in these paths. */
41
+ reactIncludes?: string[];
42
+ /** Enable React Compiler rules. Set to true to enforce as errors, or 'warn' for warnings (recommended when preparing a codebase for React Compiler adoption). */
39
43
  reactCompiler?: boolean | 'warn';
40
44
  /** Enable TypeScript-specific rules */
41
45
  ts?: boolean;
42
46
  /** Disables expensive rules for performance */
43
47
  performanceMode?: boolean;
44
- /** Additional directories to ignore (added to defaults: dist, build) */
48
+ /** Additional directories to ignore (added to defaults: node_modules, dist, build, coverage) */
45
49
  ignores?: string[];
46
- /** Directories containing React files (for projects using .js for both React and Node) */
47
- reactDirs?: string[];
48
- /** Directories to ignore for Node-specific rules only */
49
- nodeIgnoreDirs?: string[];
50
+ /** Directories and files containing Node.js code. When set, Node-specific rules only apply to these paths. */
51
+ nodeIncludes?: string[];
50
52
  /** Export patterns to ignore for import rules */
51
53
  ignoreExports?: string[];
52
54
  /** Additional file patterns to allow dev dependencies in (for no-extraneous-dependencies rule) */
@@ -117,12 +119,12 @@ declare const internals: Internals;
117
119
  * @returns ESLint flat config array.
118
120
  *
119
121
  * @example
120
- * // With options object (using default export)
121
- * export default defineZenoConfig({ react: true, ts: true })
122
+ * // React + TypeScript
123
+ * export default defineZenoConfig({ reactIncludes: ['src'], ts: true })
122
124
  *
123
125
  * @example
124
126
  * // With additional config
125
- * export default defineZenoConfig({ react: true }, [customConfig])
127
+ * export default defineZenoConfig({ reactIncludes: ['src'], ts: true }, [customConfig])
126
128
  *
127
129
  * @example
128
130
  * // With config array only
@@ -9,6 +9,7 @@ import unicornPlugin from 'eslint-plugin-unicorn';
9
9
  import reactPlugin from 'eslint-plugin-react';
10
10
  import reactHooksPlugin from 'eslint-plugin-react-hooks';
11
11
  import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
12
+ import reactRefreshPlugin from 'eslint-plugin-react-refresh';
12
13
  import reactYouMightNotNeedAnEffectPlugin from 'eslint-plugin-react-you-might-not-need-an-effect';
13
14
  import typescriptEslint from 'typescript-eslint';
14
15
  import getBaseRules from './rules/baseRules.js';
@@ -18,6 +19,7 @@ import getReactHooksPluginRules from './rules/reactHooksPluginRules.js';
18
19
  import getReactCompilerPluginRules from './rules/reactCompilerPluginRules.js';
19
20
  import getStylisticPluginRules from './rules/stylisticPluginRules.js';
20
21
  import getNodePluginRules from './rules/nodePluginRules.js';
22
+ import getReactRefreshPluginRules from './rules/reactRefreshPluginRules.js';
21
23
  import getReactYouMightNotNeedAnEffectPluginRules from './rules/reactYouMightNotNeedAnEffectPluginRules.js';
22
24
  import getJsxA11yPluginRules from './rules/jsxA11yPluginRules.js';
23
25
  import getUnicornPluginRules from './rules/unicornPluginRules.js';
@@ -46,6 +48,17 @@ const defaultIgnoreDirs = [
46
48
  '**/coverage/*',
47
49
  ];
48
50
 
51
+ const isFile = (entry) => /\.\w+$/.test(entry);
52
+
53
+ const buildFilePatterns = (includes, extensionsString) => {
54
+ return includes.flatMap((entry) => {
55
+ if (isFile(entry)) {
56
+ return [entry];
57
+ }
58
+ return [`${entry}/**/*{${extensionsString}}`];
59
+ });
60
+ };
61
+
49
62
  /**
50
63
  * Creates the base ESLint configuration.
51
64
  *
@@ -54,6 +67,7 @@ const defaultIgnoreDirs = [
54
67
  * @param {string[]} [options.additionalDevDependencies] - Additional file patterns to allow dev dependencies in (for no-extraneous-dependencies rule).
55
68
  * @param {Object} [options.extensionsIgnorePattern] - Extension patterns to ignore for import rules.
56
69
  * @param {string} [options.webpackConfig] - Path to webpack config for import resolver.
70
+ * @param {boolean} [options.ts=false] - Enable TypeScript import resolution.
57
71
  * @param {boolean} [options.performanceMode=false] - Disables expensive rules for performance.
58
72
  * @returns {Array} ESLint flat config array.
59
73
  */
@@ -72,6 +86,7 @@ const baseConfig = (options = {}) => {
72
86
  settings: {
73
87
  'import-x/resolver': {
74
88
  node: { extensions: allExtensions },
89
+ ...(options.ts ? { typescript: true } : {}),
75
90
  ...(options.webpackConfig
76
91
  ? { webpack: { config: options.webpackConfig } }
77
92
  : {}),
@@ -106,22 +121,29 @@ const baseConfig = (options = {}) => {
106
121
  * Creates the Node.js-specific ESLint configuration.
107
122
  *
108
123
  * @param {Object} [options={}] - Configuration options.
109
- * @param {string[]} [options.ignoreDirs] - Additional directories to ignore for Node-specific rules.
124
+ * @param {string[]} [options.includes] - Directories and files to apply Node-specific rules to. When set, Node rules only apply to these paths.
125
+ * @param {string[]} [options.ignoreDirs] - Directories to exclude from Node-specific rules (used internally for auto-exclude).
110
126
  * @returns {Array} ESLint flat config array.
111
127
  */
112
128
  const nodeConfig = (options = {}) => {
129
+ let files = [`**/*{${nodeExtensionsString}}`];
113
130
  let ignores = [...defaultIgnoreDirs];
114
- if (options.ignoreDirs && options.ignoreDirs.length > 0) {
131
+
132
+ if (options.includes?.length > 0) {
133
+ files = buildFilePatterns(options.includes, nodeExtensionsString);
134
+ ignores = [];
135
+ } else if (options.ignoreDirs?.length > 0) {
115
136
  const optionsIgnoreDirs = options.ignoreDirs.map((dir) => {
116
137
  return `${dir}/**/*{${nodeExtensionsString}}`;
117
138
  });
118
139
  ignores = [...ignores, ...optionsIgnoreDirs];
119
140
  }
141
+
120
142
  return [
121
143
  {
122
144
  name: 'zeno/node',
123
- files: [`**/*{${nodeExtensionsString}}`],
124
- ignores,
145
+ files,
146
+ ...(ignores.length > 0 ? { ignores } : {}),
125
147
  languageOptions: {
126
148
  ecmaVersion: 'latest',
127
149
  sourceType: 'module',
@@ -141,24 +163,21 @@ const nodeConfig = (options = {}) => {
141
163
  * Creates the React-specific ESLint configuration.
142
164
  *
143
165
  * @param {Object} [options={}] - Configuration options.
144
- * @param {string[]} [options.reactDirs] - Directories containing React files (for projects using .js for both React and Node).
166
+ * @param {string[]} [options.includes] - Directories and files containing React code. Setting this enables React rules for all file types in these paths.
145
167
  * @param {Object} [options.extensionsIgnorePattern] - Extension patterns to ignore for import rules.
146
168
  * @param {boolean|string} [options.reactCompiler=false] - Enable React Compiler rules. Set to 'warn' for warnings or true for errors.
147
169
  * @returns {Array} ESLint flat config array.
148
170
  */
149
171
  const reactConfig = (options = {}) => {
150
- let files = [`**/*{${reactExtensionsString}}`];
151
- let extensions = reactExtensions;
172
+ let files;
173
+ let extensions;
152
174
 
153
- if (
154
- options.reactDirs &&
155
- Array.isArray(options.reactDirs) &&
156
- options.reactDirs.length > 0
157
- ) {
158
- files = options.reactDirs.map((dir) => {
159
- return `${dir}/**/*{${reactExtensionsExtendedString}}`;
160
- });
175
+ if (options.includes?.length > 0) {
176
+ files = buildFilePatterns(options.includes, allExtensionsString);
161
177
  extensions = reactExtensionsExtended;
178
+ } else {
179
+ files = [`**/*{${reactExtensionsString}}`];
180
+ extensions = reactExtensions;
162
181
  }
163
182
 
164
183
  return [
@@ -186,6 +205,7 @@ const reactConfig = (options = {}) => {
186
205
  ...(options.reactCompiler
187
206
  ? getReactCompilerPluginRules(options.reactCompiler)
188
207
  : {}),
208
+ ...getReactRefreshPluginRules(),
189
209
  ...getReactYouMightNotNeedAnEffectPluginRules(),
190
210
  ...getJsxA11yPluginRules(),
191
211
 
@@ -206,6 +226,7 @@ const reactConfig = (options = {}) => {
206
226
  reactPlugin.configs.flat.recommended,
207
227
  reactPlugin.configs.flat['jsx-runtime'],
208
228
  reactHooksPlugin.configs.flat.recommended,
229
+ reactRefreshPlugin.configs.recommended,
209
230
  reactYouMightNotNeedAnEffectPlugin.configs.recommended,
210
231
  jsxA11yPlugin.flatConfigs.recommended,
211
232
  ],
@@ -302,6 +323,7 @@ const internals = {
302
323
  getReactPluginRules,
303
324
  getReactHooksPluginRules,
304
325
  getReactCompilerPluginRules,
326
+ getReactRefreshPluginRules,
305
327
  getReactYouMightNotNeedAnEffectPluginRules,
306
328
  getJsxA11yPluginRules,
307
329
  },
@@ -311,13 +333,12 @@ const internals = {
311
333
  * Defines a Zeno ESLint configuration.
312
334
  *
313
335
  * @param {Object|Array} arg1 - Options object or additional config array. If an array, treated as additional config.
314
- * @param {boolean} [arg1.react=false] - Enable React-specific rules.
315
- * @param {boolean|string} [arg1.reactCompiler=false] - Enable React Compiler rules. Set to 'warn' for warnings or true for errors.
316
- * @param {boolean} [arg1.ts=true] - Enable TypeScript-specific rules.
336
+ * @param {string[]} [arg1.reactIncludes=[]] - Directories and files containing React code. Setting this enables React rules for all file types in these paths.
337
+ * @param {boolean|string} [arg1.reactCompiler=false] - Enable React Compiler rules. Set to true to enforce as errors, or 'warn' for warnings (recommended when preparing a codebase for React Compiler adoption).
338
+ * @param {boolean} [arg1.ts=false] - Enable TypeScript-specific rules.
317
339
  * @param {boolean} [arg1.performanceMode=false] - Disables expensive rules for performance.
318
340
  * @param {string[]} [arg1.ignores=[]] - Additional directories to ignore (added to defaults: dist, build).
319
- * @param {string[]} [arg1.reactDirs=[]] - Directories containing React files (for projects using .js for both React and Node).
320
- * @param {string[]} [arg1.nodeIgnoreDirs=[]] - Directories to ignore for Node-specific rules only.
341
+ * @param {string[]} [arg1.nodeIncludes=[]] - Directories and files containing Node.js code. When set, Node-specific rules only apply to these paths.
321
342
  * @param {string[]} [arg1.ignoreExports=[]] - Export patterns to ignore for import rules.
322
343
  * @param {string[]} [arg1.additionalDevDependencies=[]] - Additional file patterns to allow dev dependencies in (for no-extraneous-dependencies rule).
323
344
  * @param {Object} [arg1.extensionsIgnorePattern={}] - Extension patterns to ignore for import rules.
@@ -326,12 +347,12 @@ const internals = {
326
347
  * @returns {Array} ESLint flat config array.
327
348
  *
328
349
  * @example
329
- * // With options object
330
- * defineZenoConfig({ react: true, ts: true })
350
+ * // React + TypeScript
351
+ * defineZenoConfig({ reactIncludes: ['src'], ts: true })
331
352
  *
332
353
  * @example
333
354
  * // With additional config
334
- * defineZenoConfig({ react: true }, [customConfig])
355
+ * defineZenoConfig({ reactIncludes: ['src'], ts: true }, [customConfig])
335
356
  *
336
357
  * @example
337
358
  * // With config array only
@@ -339,17 +360,14 @@ const internals = {
339
360
  */
340
361
  const defineZenoConfig = (arg1, arg2) => {
341
362
  let options = {
342
- react: false,
343
363
  reactCompiler: false,
344
364
  ts: false,
345
365
  performanceMode: false,
346
366
 
347
- // additional directories to ignore (added to defaults: dist, build)
348
367
  ignores: [],
349
368
 
350
- // if a project uses .js file extension for both react and node files this will help separate the rules for each
351
- reactDirs: [],
352
- nodeIgnoreDirs: [],
369
+ reactIncludes: [],
370
+ nodeIncludes: [],
353
371
 
354
372
  ignoreExports: [],
355
373
  additionalDevDependencies: [],
@@ -369,11 +387,11 @@ const defineZenoConfig = (arg1, arg2) => {
369
387
  if (!Array.isArray(options.ignores)) {
370
388
  options.ignores = [];
371
389
  }
372
- if (!Array.isArray(options.reactDirs)) {
373
- options.reactDirs = [];
390
+ if (!Array.isArray(options.reactIncludes)) {
391
+ options.reactIncludes = [];
374
392
  }
375
- if (!Array.isArray(options.nodeIgnoreDirs)) {
376
- options.nodeIgnoreDirs = [];
393
+ if (!Array.isArray(options.nodeIncludes)) {
394
+ options.nodeIncludes = [];
377
395
  }
378
396
  if (!Array.isArray(options.ignoreExports)) {
379
397
  options.ignoreExports = [];
@@ -388,25 +406,31 @@ const defineZenoConfig = (arg1, arg2) => {
388
406
  options.extensionsIgnorePattern = {};
389
407
  }
390
408
 
391
- // use the reactDirs as the nodeIgnoreDirs if they are not set since they would likely be the same
392
- if (
393
- options.react &&
394
- options.reactDirs.length > 0 &&
395
- options.nodeIgnoreDirs.length === 0
396
- ) {
397
- options.nodeIgnoreDirs = [...options.reactDirs];
409
+ const isReact = options.reactIncludes.length > 0;
410
+
411
+ // Determine Node config options
412
+ let nodeOptions = {};
413
+ if (options.nodeIncludes.length > 0) {
414
+ nodeOptions = { includes: options.nodeIncludes };
415
+ } else if (isReact) {
416
+ // Auto-exclude reactIncludes directories from Node rules
417
+ const reactDirs = options.reactIncludes.filter(
418
+ (entry) => !isFile(entry)
419
+ );
420
+ if (reactDirs.length > 0) {
421
+ nodeOptions = { ignoreDirs: reactDirs };
422
+ }
398
423
  }
399
424
 
400
- // Load optional configs if needed
401
- const reactConfigResult = options.react
425
+ const reactConfigResult = isReact
402
426
  ? configs.getReact({
403
- reactDirs: options.reactDirs,
427
+ includes: options.reactIncludes,
404
428
  extensionsIgnorePattern: options.extensionsIgnorePattern,
405
429
  reactCompiler: options.reactCompiler,
406
430
  })
407
431
  : [];
408
432
  const tsConfigResult = options.ts
409
- ? configs.getTypescript({ react: options.react })
433
+ ? configs.getTypescript({ react: isReact })
410
434
  : [];
411
435
 
412
436
  return defineConfig([
@@ -415,12 +439,11 @@ const defineZenoConfig = (arg1, arg2) => {
415
439
  ignoreExports: options.ignoreExports,
416
440
  additionalDevDependencies: options.additionalDevDependencies,
417
441
  webpackConfig: options.webpackConfig,
442
+ ts: options.ts,
418
443
  extensionsIgnorePattern: options.extensionsIgnorePattern,
419
444
  performanceMode: options.performanceMode,
420
445
  }),
421
- ...configs.getNode({
422
- ignoreDirs: options.nodeIgnoreDirs,
423
- }),
446
+ ...configs.getNode(nodeOptions),
424
447
  ...reactConfigResult,
425
448
  ...tsConfigResult,
426
449
 
@@ -119,6 +119,7 @@ const getImportPluginRules = (options = {}) => {
119
119
  commonjs: true,
120
120
  caseSensitive: true,
121
121
  caseSensitiveStrict: true,
122
+ ignore: ['\\?'], // ignore query params (example: svg imports in vite)
122
123
  },
123
124
  ],
124
125
 
@@ -154,7 +155,7 @@ const getImportPluginRules = (options = {}) => {
154
155
  'import-x/max-dependencies': 'off',
155
156
 
156
157
  // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/newline-after-import.md
157
- 'import-x/newline-after-import': ['warn', { considerComments: true }],
158
+ 'import-x/newline-after-import': ['warn', { considerComments: false }],
158
159
 
159
160
  // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-anonymous-default-export.md
160
161
  'import-x/no-anonymous-default-export': 'off',
@@ -0,0 +1,8 @@
1
+ const getReactRefreshPluginRules = () => {
2
+ return {
3
+ // https://github.com/ArnaudBarre/eslint-plugin-react-refresh
4
+ 'react-refresh/only-export-components': 'warn',
5
+ };
6
+ };
7
+
8
+ export default getReactRefreshPluginRules;
@@ -23,7 +23,7 @@ declare const reactJsExtensionsExtended: string[];
23
23
  /** String version of reactJsExtensionsExtended for use in glob patterns */
24
24
  declare const reactJsExtensionsExtendedString: string;
25
25
 
26
- /** Extended React extensions (includes .js, .jsx, and .tsx) */
26
+ /** Extended React extensions (includes .js, .jsx, .ts, and .tsx) */
27
27
  declare const reactExtensionsExtended: string[];
28
28
  /** String version of reactExtensionsExtended for use in glob patterns */
29
29
  declare const reactExtensionsExtendedString: string;
package/src/extensions.js CHANGED
@@ -18,6 +18,7 @@ const reactJsExtensionsExtended = [...jsExtensions, ...jsxExtensions];
18
18
  const reactExtensionsExtended = [
19
19
  ...jsExtensions,
20
20
  ...jsxExtensions,
21
+ ...tsExtensions,
21
22
  ...tsxExtensions,
22
23
  ];
23
24
  const typescriptExtensions = [...tsExtensions, ...tsxExtensions];