zeno-config 4.0.3 → 5.1.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 +31 -23
- package/package.json +3 -1
- package/src/eslint/index.d.ts +15 -15
- package/src/eslint/index.js +66 -46
- package/src/eslint/rules/importPluginRules.js +2 -1
- package/src/eslint/rules/reactRefreshPluginRules.js +8 -0
- package/src/eslint/rules/unicornPluginRules.js +1 -1
- package/src/extensions.d.ts +1 -1
- package/src/extensions.js +1 -0
- package/src/tsconfig.base.json +1 -0
- package/src/tsconfig.server.json +13 -0
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
|
-
//
|
|
57
|
+
// Full enforcement — compiler rules as errors
|
|
58
58
|
export default defineZenoConfig({
|
|
59
|
-
|
|
60
|
-
reactCompiler:
|
|
59
|
+
reactIncludes: ['src'],
|
|
60
|
+
reactCompiler: true,
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
//
|
|
63
|
+
// Preparing a codebase — surface compiler violations as warnings
|
|
64
64
|
export default defineZenoConfig({
|
|
65
|
-
|
|
66
|
-
reactCompiler:
|
|
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
|
-
//
|
|
93
|
-
|
|
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
|
-
//
|
|
96
|
-
|
|
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
|
-
//
|
|
99
|
-
|
|
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: ['^@/'],
|
|
@@ -158,6 +157,15 @@ For Node.js projects, extend the provided TypeScript config in your `tsconfig.js
|
|
|
158
157
|
}
|
|
159
158
|
```
|
|
160
159
|
|
|
160
|
+
For backend servers using bundlers like `tsup` or `tsx`:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"extends": "zeno-config/tsconfig-server"
|
|
165
|
+
// your tsconfig options
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
161
169
|
For React projects:
|
|
162
170
|
|
|
163
171
|
```json
|
|
@@ -218,7 +226,7 @@ import {
|
|
|
218
226
|
reactJsExtensions, // JSX-only extensions: .jsx, .mjsx, .cjsx
|
|
219
227
|
reactJsExtensionsExtended, // JS + JSX extensions: .js, .mjs, .cjs, .jsx, .mjsx, .cjsx
|
|
220
228
|
reactExtensions, // React extensions (JSX + TSX): .jsx, .mjsx, .cjsx, .tsx, .mtsx, .ctsx
|
|
221
|
-
reactExtensionsExtended, //
|
|
229
|
+
reactExtensionsExtended, // All extensions for React directories: .js, .mjs, .cjs, .jsx, .mjsx, .cjsx, .ts, .cts, .mts, .tsx, .mtsx, .ctsx
|
|
222
230
|
typescriptExtensions, // TypeScript extensions: .ts, .cts, .mts, .tsx, .mtsx, .ctsx
|
|
223
231
|
|
|
224
232
|
// String versions for glob patterns (comma-separated)
|
|
@@ -227,7 +235,7 @@ import {
|
|
|
227
235
|
reactJsExtensionsString, // ".jsx,.mjsx,.cjsx"
|
|
228
236
|
reactJsExtensionsExtendedString, // ".js,.mjs,.cjs,.jsx,.mjsx,.cjsx"
|
|
229
237
|
reactExtensionsString, // ".jsx,.mjsx,.cjsx,.tsx,.mtsx,.ctsx"
|
|
230
|
-
reactExtensionsExtendedString, // ".js,.mjs,.cjs,.jsx,.mjsx,.cjsx,.tsx,.mtsx,.ctsx"
|
|
238
|
+
reactExtensionsExtendedString, // ".js,.mjs,.cjs,.jsx,.mjsx,.cjsx,.ts,.cts,.mts,.tsx,.mtsx,.ctsx"
|
|
231
239
|
typescriptExtensionsString, // ".ts,.cts,.mts,.tsx,.mtsx,.ctsx"
|
|
232
240
|
} from 'zeno-config/extensions';
|
|
233
241
|
```
|
|
@@ -236,13 +244,12 @@ import {
|
|
|
236
244
|
|
|
237
245
|
| Option | Type | Default | Description |
|
|
238
246
|
| --------------------------- | ----------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
239
|
-
| `
|
|
240
|
-
| `reactCompiler` | `boolean \| 'warn'` | `false` | Enable React Compiler rules. Set to `'warn'` to surface violations as warnings (
|
|
247
|
+
| `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. |
|
|
248
|
+
| `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
249
|
| `ts` | `boolean` | `false` | Enable TypeScript-specific rules |
|
|
242
250
|
| `performanceMode` | `boolean` | `false` | Disables expensive rules for better performance |
|
|
243
251
|
| `ignores` | `string[]` | `[]` | Additional directories to ignore (added to defaults: node_modules, dist, build, coverage) |
|
|
244
|
-
| `
|
|
245
|
-
| `nodeIgnoreDirs` | `string[]` | `[]` | Directories to ignore for Node-specific rules (defaults to `reactDirs` if not set) |
|
|
252
|
+
| `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
253
|
| `ignoreExports` | `string[]` | `[]` | Export patterns to ignore for import/no-unresolved rule |
|
|
247
254
|
| `additionalDevDependencies` | `string[]` | `[]` | Additional file patterns to allow dev dependencies in (for import/no-extraneous-dependencies) |
|
|
248
255
|
| `extensionsIgnorePattern` | `object` | `{}` | Extension patterns to ignore for import/extensions rule |
|
|
@@ -261,9 +268,9 @@ const { configs, rules, extensions } = zenoInternals;
|
|
|
261
268
|
|
|
262
269
|
export default [
|
|
263
270
|
...configs.getBase(),
|
|
264
|
-
...configs.getNode(),
|
|
265
|
-
...configs.getReact(),
|
|
266
|
-
...configs.getTypescript(),
|
|
271
|
+
...configs.getNode({ includes: ['src/server'] }),
|
|
272
|
+
...configs.getReact({ includes: ['src'] }),
|
|
273
|
+
...configs.getTypescript({ react: true }),
|
|
267
274
|
// Your custom configs
|
|
268
275
|
];
|
|
269
276
|
```
|
|
@@ -300,6 +307,7 @@ See [src/prettier.js](src/prettier.js) for the default Prettier configuration.
|
|
|
300
307
|
See the TypeScript configuration files:
|
|
301
308
|
|
|
302
309
|
- [src/tsconfig.base.json](src/tsconfig.base.json) - Base configuration for Node.js projects
|
|
310
|
+
- [src/tsconfig.server.json](src/tsconfig.server.json) - Configuration for backend servers using bundlers like tsup/tsx (extends base)
|
|
303
311
|
- [src/tsconfig.react.json](src/tsconfig.react.json) - Configuration for React projects (extends base)
|
|
304
312
|
|
|
305
313
|
### Included Plugins
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zeno-config",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.1.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",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"default": "./src/prettier.js"
|
|
37
37
|
},
|
|
38
38
|
"./tsconfig": "./src/tsconfig.base.json",
|
|
39
|
+
"./tsconfig-server": "./src/tsconfig.server.json",
|
|
39
40
|
"./tsconfig-react": "./src/tsconfig.react.json",
|
|
40
41
|
"./extensions": {
|
|
41
42
|
"types": "./src/extensions.d.ts",
|
|
@@ -76,6 +77,7 @@
|
|
|
76
77
|
"eslint-plugin-prettier": "5.5.5",
|
|
77
78
|
"eslint-plugin-react": "7.37.5",
|
|
78
79
|
"eslint-plugin-react-hooks": "7.0.1",
|
|
80
|
+
"eslint-plugin-react-refresh": "0.5.2",
|
|
79
81
|
"eslint-plugin-react-you-might-not-need-an-effect": "0.9.2",
|
|
80
82
|
"eslint-plugin-unicorn": "63.0.0",
|
|
81
83
|
"globals": "17.4.0",
|
package/src/eslint/index.d.ts
CHANGED
|
@@ -16,16 +16,18 @@ interface BaseConfigOptions {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
interface NodeConfigOptions {
|
|
19
|
-
/**
|
|
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) */
|
|
20
22
|
ignoreDirs?: string[];
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
interface ReactConfigOptions {
|
|
24
|
-
/** Directories containing React
|
|
25
|
-
|
|
26
|
+
/** Directories and files containing React code. Setting this enables React rules for all file types in these paths. */
|
|
27
|
+
includes?: string[];
|
|
26
28
|
/** Extension patterns to ignore for import rules */
|
|
27
29
|
extensionsIgnorePattern?: Record<string, string>;
|
|
28
|
-
/** Enable React Compiler rules. Set to 'warn' for warnings
|
|
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). */
|
|
29
31
|
reactCompiler?: boolean | 'warn';
|
|
30
32
|
}
|
|
31
33
|
|
|
@@ -35,20 +37,18 @@ interface TypescriptConfigOptions {
|
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
interface DefineZenoConfigOptions {
|
|
38
|
-
/**
|
|
39
|
-
|
|
40
|
-
/** Enable React Compiler rules. Set to 'warn' for warnings
|
|
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). */
|
|
41
43
|
reactCompiler?: boolean | 'warn';
|
|
42
44
|
/** Enable TypeScript-specific rules */
|
|
43
45
|
ts?: boolean;
|
|
44
46
|
/** Disables expensive rules for performance */
|
|
45
47
|
performanceMode?: boolean;
|
|
46
|
-
/** Additional directories to ignore (added to defaults: dist, build) */
|
|
48
|
+
/** Additional directories to ignore (added to defaults: node_modules, dist, build, coverage) */
|
|
47
49
|
ignores?: string[];
|
|
48
|
-
/** Directories containing
|
|
49
|
-
|
|
50
|
-
/** Directories to ignore for Node-specific rules only */
|
|
51
|
-
nodeIgnoreDirs?: string[];
|
|
50
|
+
/** Directories and files containing Node.js code. When set, Node-specific rules only apply to these paths. */
|
|
51
|
+
nodeIncludes?: string[];
|
|
52
52
|
/** Export patterns to ignore for import rules */
|
|
53
53
|
ignoreExports?: string[];
|
|
54
54
|
/** Additional file patterns to allow dev dependencies in (for no-extraneous-dependencies rule) */
|
|
@@ -119,12 +119,12 @@ declare const internals: Internals;
|
|
|
119
119
|
* @returns ESLint flat config array.
|
|
120
120
|
*
|
|
121
121
|
* @example
|
|
122
|
-
* //
|
|
123
|
-
* export default defineZenoConfig({
|
|
122
|
+
* // React + TypeScript
|
|
123
|
+
* export default defineZenoConfig({ reactIncludes: ['src'], ts: true })
|
|
124
124
|
*
|
|
125
125
|
* @example
|
|
126
126
|
* // With additional config
|
|
127
|
-
* export default defineZenoConfig({
|
|
127
|
+
* export default defineZenoConfig({ reactIncludes: ['src'], ts: true }, [customConfig])
|
|
128
128
|
*
|
|
129
129
|
* @example
|
|
130
130
|
* // With config array only
|
package/src/eslint/index.js
CHANGED
|
@@ -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
|
*
|
|
@@ -108,22 +121,29 @@ const baseConfig = (options = {}) => {
|
|
|
108
121
|
* Creates the Node.js-specific ESLint configuration.
|
|
109
122
|
*
|
|
110
123
|
* @param {Object} [options={}] - Configuration options.
|
|
111
|
-
* @param {string[]} [options.
|
|
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).
|
|
112
126
|
* @returns {Array} ESLint flat config array.
|
|
113
127
|
*/
|
|
114
128
|
const nodeConfig = (options = {}) => {
|
|
129
|
+
let files = [`**/*{${nodeExtensionsString}}`];
|
|
115
130
|
let ignores = [...defaultIgnoreDirs];
|
|
116
|
-
|
|
131
|
+
|
|
132
|
+
if (options.includes?.length > 0) {
|
|
133
|
+
files = buildFilePatterns(options.includes, nodeExtensionsString);
|
|
134
|
+
ignores = [];
|
|
135
|
+
} else if (options.ignoreDirs?.length > 0) {
|
|
117
136
|
const optionsIgnoreDirs = options.ignoreDirs.map((dir) => {
|
|
118
137
|
return `${dir}/**/*{${nodeExtensionsString}}`;
|
|
119
138
|
});
|
|
120
139
|
ignores = [...ignores, ...optionsIgnoreDirs];
|
|
121
140
|
}
|
|
141
|
+
|
|
122
142
|
return [
|
|
123
143
|
{
|
|
124
144
|
name: 'zeno/node',
|
|
125
|
-
files
|
|
126
|
-
ignores,
|
|
145
|
+
files,
|
|
146
|
+
...(ignores.length > 0 ? { ignores } : {}),
|
|
127
147
|
languageOptions: {
|
|
128
148
|
ecmaVersion: 'latest',
|
|
129
149
|
sourceType: 'module',
|
|
@@ -143,24 +163,21 @@ const nodeConfig = (options = {}) => {
|
|
|
143
163
|
* Creates the React-specific ESLint configuration.
|
|
144
164
|
*
|
|
145
165
|
* @param {Object} [options={}] - Configuration options.
|
|
146
|
-
* @param {string[]} [options.
|
|
166
|
+
* @param {string[]} [options.includes] - Directories and files containing React code. Setting this enables React rules for all file types in these paths.
|
|
147
167
|
* @param {Object} [options.extensionsIgnorePattern] - Extension patterns to ignore for import rules.
|
|
148
168
|
* @param {boolean|string} [options.reactCompiler=false] - Enable React Compiler rules. Set to 'warn' for warnings or true for errors.
|
|
149
169
|
* @returns {Array} ESLint flat config array.
|
|
150
170
|
*/
|
|
151
171
|
const reactConfig = (options = {}) => {
|
|
152
|
-
let files
|
|
153
|
-
let extensions
|
|
172
|
+
let files;
|
|
173
|
+
let extensions;
|
|
154
174
|
|
|
155
|
-
if (
|
|
156
|
-
options.
|
|
157
|
-
Array.isArray(options.reactDirs) &&
|
|
158
|
-
options.reactDirs.length > 0
|
|
159
|
-
) {
|
|
160
|
-
files = options.reactDirs.map((dir) => {
|
|
161
|
-
return `${dir}/**/*{${reactExtensionsExtendedString}}`;
|
|
162
|
-
});
|
|
175
|
+
if (options.includes?.length > 0) {
|
|
176
|
+
files = buildFilePatterns(options.includes, allExtensionsString);
|
|
163
177
|
extensions = reactExtensionsExtended;
|
|
178
|
+
} else {
|
|
179
|
+
files = [`**/*{${reactExtensionsString}}`];
|
|
180
|
+
extensions = reactExtensions;
|
|
164
181
|
}
|
|
165
182
|
|
|
166
183
|
return [
|
|
@@ -188,6 +205,7 @@ const reactConfig = (options = {}) => {
|
|
|
188
205
|
...(options.reactCompiler
|
|
189
206
|
? getReactCompilerPluginRules(options.reactCompiler)
|
|
190
207
|
: {}),
|
|
208
|
+
...getReactRefreshPluginRules(),
|
|
191
209
|
...getReactYouMightNotNeedAnEffectPluginRules(),
|
|
192
210
|
...getJsxA11yPluginRules(),
|
|
193
211
|
|
|
@@ -208,6 +226,7 @@ const reactConfig = (options = {}) => {
|
|
|
208
226
|
reactPlugin.configs.flat.recommended,
|
|
209
227
|
reactPlugin.configs.flat['jsx-runtime'],
|
|
210
228
|
reactHooksPlugin.configs.flat.recommended,
|
|
229
|
+
reactRefreshPlugin.configs.recommended,
|
|
211
230
|
reactYouMightNotNeedAnEffectPlugin.configs.recommended,
|
|
212
231
|
jsxA11yPlugin.flatConfigs.recommended,
|
|
213
232
|
],
|
|
@@ -304,6 +323,7 @@ const internals = {
|
|
|
304
323
|
getReactPluginRules,
|
|
305
324
|
getReactHooksPluginRules,
|
|
306
325
|
getReactCompilerPluginRules,
|
|
326
|
+
getReactRefreshPluginRules,
|
|
307
327
|
getReactYouMightNotNeedAnEffectPluginRules,
|
|
308
328
|
getJsxA11yPluginRules,
|
|
309
329
|
},
|
|
@@ -313,13 +333,12 @@ const internals = {
|
|
|
313
333
|
* Defines a Zeno ESLint configuration.
|
|
314
334
|
*
|
|
315
335
|
* @param {Object|Array} arg1 - Options object or additional config array. If an array, treated as additional config.
|
|
316
|
-
* @param {
|
|
317
|
-
* @param {boolean|string} [arg1.reactCompiler=false] - Enable React Compiler rules. Set to 'warn' for warnings
|
|
318
|
-
* @param {boolean} [arg1.ts=
|
|
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.
|
|
319
339
|
* @param {boolean} [arg1.performanceMode=false] - Disables expensive rules for performance.
|
|
320
340
|
* @param {string[]} [arg1.ignores=[]] - Additional directories to ignore (added to defaults: dist, build).
|
|
321
|
-
* @param {string[]} [arg1.
|
|
322
|
-
* @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.
|
|
323
342
|
* @param {string[]} [arg1.ignoreExports=[]] - Export patterns to ignore for import rules.
|
|
324
343
|
* @param {string[]} [arg1.additionalDevDependencies=[]] - Additional file patterns to allow dev dependencies in (for no-extraneous-dependencies rule).
|
|
325
344
|
* @param {Object} [arg1.extensionsIgnorePattern={}] - Extension patterns to ignore for import rules.
|
|
@@ -328,12 +347,12 @@ const internals = {
|
|
|
328
347
|
* @returns {Array} ESLint flat config array.
|
|
329
348
|
*
|
|
330
349
|
* @example
|
|
331
|
-
* //
|
|
332
|
-
* defineZenoConfig({
|
|
350
|
+
* // React + TypeScript
|
|
351
|
+
* defineZenoConfig({ reactIncludes: ['src'], ts: true })
|
|
333
352
|
*
|
|
334
353
|
* @example
|
|
335
354
|
* // With additional config
|
|
336
|
-
* defineZenoConfig({
|
|
355
|
+
* defineZenoConfig({ reactIncludes: ['src'], ts: true }, [customConfig])
|
|
337
356
|
*
|
|
338
357
|
* @example
|
|
339
358
|
* // With config array only
|
|
@@ -341,17 +360,14 @@ const internals = {
|
|
|
341
360
|
*/
|
|
342
361
|
const defineZenoConfig = (arg1, arg2) => {
|
|
343
362
|
let options = {
|
|
344
|
-
react: false,
|
|
345
363
|
reactCompiler: false,
|
|
346
364
|
ts: false,
|
|
347
365
|
performanceMode: false,
|
|
348
366
|
|
|
349
|
-
// additional directories to ignore (added to defaults: dist, build)
|
|
350
367
|
ignores: [],
|
|
351
368
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
nodeIgnoreDirs: [],
|
|
369
|
+
reactIncludes: [],
|
|
370
|
+
nodeIncludes: [],
|
|
355
371
|
|
|
356
372
|
ignoreExports: [],
|
|
357
373
|
additionalDevDependencies: [],
|
|
@@ -371,11 +387,11 @@ const defineZenoConfig = (arg1, arg2) => {
|
|
|
371
387
|
if (!Array.isArray(options.ignores)) {
|
|
372
388
|
options.ignores = [];
|
|
373
389
|
}
|
|
374
|
-
if (!Array.isArray(options.
|
|
375
|
-
options.
|
|
390
|
+
if (!Array.isArray(options.reactIncludes)) {
|
|
391
|
+
options.reactIncludes = [];
|
|
376
392
|
}
|
|
377
|
-
if (!Array.isArray(options.
|
|
378
|
-
options.
|
|
393
|
+
if (!Array.isArray(options.nodeIncludes)) {
|
|
394
|
+
options.nodeIncludes = [];
|
|
379
395
|
}
|
|
380
396
|
if (!Array.isArray(options.ignoreExports)) {
|
|
381
397
|
options.ignoreExports = [];
|
|
@@ -390,25 +406,31 @@ const defineZenoConfig = (arg1, arg2) => {
|
|
|
390
406
|
options.extensionsIgnorePattern = {};
|
|
391
407
|
}
|
|
392
408
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
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
|
+
}
|
|
400
423
|
}
|
|
401
424
|
|
|
402
|
-
|
|
403
|
-
const reactConfigResult = options.react
|
|
425
|
+
const reactConfigResult = isReact
|
|
404
426
|
? configs.getReact({
|
|
405
|
-
|
|
427
|
+
includes: options.reactIncludes,
|
|
406
428
|
extensionsIgnorePattern: options.extensionsIgnorePattern,
|
|
407
429
|
reactCompiler: options.reactCompiler,
|
|
408
430
|
})
|
|
409
431
|
: [];
|
|
410
432
|
const tsConfigResult = options.ts
|
|
411
|
-
? configs.getTypescript({ react:
|
|
433
|
+
? configs.getTypescript({ react: isReact })
|
|
412
434
|
: [];
|
|
413
435
|
|
|
414
436
|
return defineConfig([
|
|
@@ -421,9 +443,7 @@ const defineZenoConfig = (arg1, arg2) => {
|
|
|
421
443
|
extensionsIgnorePattern: options.extensionsIgnorePattern,
|
|
422
444
|
performanceMode: options.performanceMode,
|
|
423
445
|
}),
|
|
424
|
-
...configs.getNode(
|
|
425
|
-
ignoreDirs: options.nodeIgnoreDirs,
|
|
426
|
-
}),
|
|
446
|
+
...configs.getNode(nodeOptions),
|
|
427
447
|
...reactConfigResult,
|
|
428
448
|
...tsConfigResult,
|
|
429
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:
|
|
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',
|
|
@@ -430,7 +430,7 @@ const getUnicornPluginRules = () => {
|
|
|
430
430
|
'unicorn/template-indent': 'off', // conflicts with prettier
|
|
431
431
|
|
|
432
432
|
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/text-encoding-identifier-case.md
|
|
433
|
-
'unicorn/text-encoding-identifier-case': '
|
|
433
|
+
'unicorn/text-encoding-identifier-case': 'off',
|
|
434
434
|
|
|
435
435
|
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/throw-new-error.md
|
|
436
436
|
'unicorn/throw-new-error': 'error', // handled by unicorn/new-for-builtins
|
package/src/extensions.d.ts
CHANGED
|
@@ -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];
|
package/src/tsconfig.base.json
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"module": "NodeNext", // Node.js native ESM
|
|
10
10
|
"moduleResolution": "NodeNext", // Node.js native ESM resolution
|
|
11
11
|
"moduleDetection": "force", // treat all files as modules
|
|
12
|
+
"resolveJsonModule": true, // allow importing .json files with type safety
|
|
12
13
|
"verbatimModuleSyntax": true, // enforce explicit import type syntax and matching module syntax
|
|
13
14
|
|
|
14
15
|
/* Emit */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"extends": "./tsconfig.base.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
/* Modules */
|
|
6
|
+
"module": "ESNext", // bundler handles module compilation
|
|
7
|
+
"moduleResolution": "bundler", // bundler-style resolution (tsup, tsx, etc.)
|
|
8
|
+
"allowImportingTsExtensions": true, // allow .ts imports (bundler resolves them)
|
|
9
|
+
|
|
10
|
+
/* Emit */
|
|
11
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.server.tsbuildinfo"
|
|
12
|
+
}
|
|
13
|
+
}
|