rhine-lint 1.4.1 → 1.4.3

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
@@ -151,8 +151,9 @@ CLI 参数优先级高于配置文件:
151
151
  - `--level <level>`: 强制指定项目类型(`js`, `ts`, `frontend`, `nextjs`)。
152
152
  - `--no-project-type-check`: 禁用基于项目的类型检查 (可加快单文件处理速度)。
153
153
  - `--tsconfig <path>`: 指定 tsconfig 文件路径 (用于类型检查和 import 解析)。
154
+ - `--ignore-file <path>`: 指定类似 `.gitignore` 的忽略文件 (支持多次使用, e.g. `--ignore-file .gitignore --ignore-file .eslintignore`)。
154
155
  - `--ignore <pattern>`: 添加忽略模式 (支持多次使用, e.g. `--ignore dist --ignore coverage`)。
155
- - `--no-ignore`: 强制禁用所有忽略规则 (包括 .gitignore)。
156
+ - `--no-ignore`: 强制禁用所有忽略规则 (包括 ignoreFiles 和 ignores)。
156
157
  - `--debug`: 打印调试信息(包括生成的配置、忽略列表等)。
157
158
  - `--cache-dir <dir>`: 指定缓存目录(默认使用 `node_modules/.cache/rhine-lint`)。
158
159
 
@@ -202,37 +203,66 @@ Rhine Lint 提供了灵活的文件忽略机制,支持多种配置方式。
202
203
  以下目录始终被忽略(无需配置):
203
204
  - `node_modules`, `dist`, `.next`, `.git`, `.output`, `.nuxt`, `coverage`, `.cache`
204
205
 
205
- #### 自动读取 .gitignore
206
+ 以下文件默认被忽略(可通过配置覆盖):
207
+ - `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `bun.lock`
206
208
 
207
- Rhine Lint 会自动解析项目根目录的 `.gitignore` 文件,将其中的模式转换为 ESLint 忽略规则。
209
+ #### 忽略文件 ignoreFiles
208
210
 
209
- #### CLI 忽略选项
211
+ Rhine Lint 会自动解析 `.gitignore` 风格的文件,将其中的模式转换为 ESLint 忽略规则。
212
+
213
+ **默认值**: `['./.gitignore']`
210
214
 
211
215
  ```bash
212
- # 添加额外的忽略模式 (支持多次使用)
213
- rl --ignore temp --ignore generated --ignore "*.test.ts"
216
+ # CLI: 指定忽略文件 (覆盖默认值,支持多次使用)
217
+ rl --ignore-file .gitignore --ignore-file .eslintignore
218
+ ```
214
219
 
215
- # 禁用所有忽略规则 (包括 .gitignore 和默认忽略)
216
- rl --no-ignore
220
+ ```typescript
221
+ // rhine-lint.config.ts
222
+ export default {
223
+ // 指定要读取的忽略文件列表
224
+ ignoreFiles: ['./.gitignore', './.eslintignore']
225
+ }
217
226
  ```
218
227
 
219
- #### 配置文件忽略
228
+ #### 忽略模式 ignores
229
+
230
+ 直接指定要忽略的文件或目录模式。
231
+
232
+ **默认值**: `['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock']`
233
+
234
+ ```bash
235
+ # CLI: 添加忽略模式 (与配置文件合并,支持多次使用)
236
+ rl --ignore temp --ignore generated --ignore "*.test.ts"
237
+ ```
220
238
 
221
239
  ```typescript
222
240
  // rhine-lint.config.ts
223
241
  export default {
224
- ignore: ['temp', 'generated', '*.test.ts']
242
+ // 指定要忽略的文件/目录模式
243
+ ignores: ['temp', 'generated', '*.test.ts']
225
244
  }
226
245
  ```
227
246
 
247
+ #### 禁用忽略 --no-ignore
248
+
249
+ ```bash
250
+ # 禁用所有忽略规则 (包括 ignoreFiles 和 ignores)
251
+ rl --no-ignore
252
+ ```
253
+
228
254
  #### 忽略模式优先级
229
255
 
230
256
  1. `--no-ignore` 会禁用所有忽略处理
231
- 2. 否则,按以下顺序合并(后面的追加到前面):
232
- - 默认忽略目录
233
- - `.gitignore` 解析结果
234
- - 配置文件 `ignore` 数组
235
- - CLI `--ignore` 参数
257
+ 2. 否则,按以下顺序合并:
258
+ - 默认忽略目录(始终生效)
259
+ - `ignoreFiles` 中各文件的解析结果
260
+ - `ignores` 模式列表
261
+
262
+ **优先级规则**:
263
+ - `--ignore-file`: CLI 指定时覆盖配置文件中的 `ignoreFiles`
264
+ - `--ignore`: CLI 指定时覆盖配置文件中的 `ignores`
265
+ - 最终 `ignoreFiles` 和 `ignores` 的结果都会生效(合并)
236
266
 
237
267
  ### 缓存目录 Cache Directory
238
268
 
@@ -303,6 +333,7 @@ cli
303
333
  .option("--level <level>", "Project level (js, ts, frontend, nextjs)")
304
334
  .option("--no-project-type-check", "Disable project-based type checking")
305
335
  .option("--tsconfig <path>", "Path to tsconfig file")
336
+ .option("--ignore-file [path]", "Add gitignore-style file (can be used multiple times)")
306
337
  .option("--ignore [pattern]", "Add ignore pattern (can be used multiple times)")
307
338
  .option("--no-ignore", "Disable all ignore rules")
308
339
  .option("--cache-dir <dir>", "Custom cache directory")
@@ -322,6 +353,13 @@ if (!noIgnore && options.ignore && options.ignore !== true) {
322
353
  ? options.ignore.filter((p: unknown) => typeof p === 'string')
323
354
  : [options.ignore];
324
355
  }
356
+ // --ignore-file 参数处理
357
+ let ignoreFiles: string[] = [];
358
+ if (!noIgnore && options.ignoreFile && options.ignoreFile !== true) {
359
+ ignoreFiles = Array.isArray(options.ignoreFile)
360
+ ? options.ignoreFile.filter((p: unknown) => typeof p === 'string')
361
+ : [options.ignoreFile];
362
+ }
325
363
  ```
326
364
 
327
365
  - **逻辑**:
@@ -345,7 +383,8 @@ export async function generateTempConfig(
345
383
  cliProjectTypeCheck?: boolean, // --no-project-type-check
346
384
  cliTsconfig?: string, // --tsconfig 参数
347
385
  cliIgnorePatterns: string[] = [], // --ignore 参数 (数组)
348
- noIgnore: boolean = false // --no-ignore 参数
386
+ noIgnore: boolean = false, // --no-ignore 参数
387
+ cliIgnoreFiles: string[] = [] // --ignore-file 参数 (数组)
349
388
  ): Promise<{ eslintPath: string; prettierPath: string; cachePath: string }>
350
389
  ```
351
390
 
@@ -355,6 +394,15 @@ export async function generateTempConfig(
355
394
  ```typescript
356
395
  const projectTypeCheck = cliProjectTypeCheck ?? userConfigResult.config.projectTypeCheck ?? true;
357
396
  const tsconfigPath = cliTsconfig ?? userConfigResult.config.tsconfig;
397
+ // ignoreFiles: CLI 覆盖 config 覆盖默认值
398
+ const resolvedIgnoreFiles = cliIgnoreFiles.length > 0
399
+ ? cliIgnoreFiles
400
+ : (userConfigResult.config.ignoreFiles ?? DEFAULT_IGNORE_FILES);
401
+ // ignores: CLI 覆盖 config 覆盖默认值
402
+ const resolvedIgnores = cliIgnorePatterns.length > 0
403
+ ? cliIgnorePatterns
404
+ : (configIgnores.length > 0 ? configIgnores : DEFAULT_IGNORES);
405
+ // 最终 ignoreFiles 和 ignores 都会生效
358
406
  ```
359
407
 
360
408
  2. **智能缓存 (SHA-256 指纹)**:
@@ -364,14 +412,18 @@ export async function generateTempConfig(
364
412
  hash.update(cliLevel || "default");
365
413
  hash.update(projectTypeCheck ? "ptc-on" : "ptc-off");
366
414
  hash.update(tsconfigPath || "default-tsconfig");
367
- hash.update(cliIgnorePatterns.join(",") || "no-cli-ignore");
415
+ hash.update(resolvedIgnoreFiles.join(",") || "no-ignore-files");
416
+ hash.update(resolvedIgnores.join(",") || "no-ignores");
368
417
  hash.update(noIgnore ? "no-ignore" : "with-ignore");
369
- // + 用户配置文件内容 + .gitignore 内容
418
+ // + 用户配置文件内容 + 各忽略文件内容
370
419
  ```
371
420
 
372
421
  3. **忽略模式处理**:
373
422
  - 若 `--no-ignore`,跳过所有忽略处理
374
- - 否则:解析 `.gitignore` → 合并默认忽略 → 合并 CLI/Config 忽略
423
+ - 否则:
424
+ 1. 添加默认始终忽略的目录
425
+ 2. 解析所有 `ignoreFiles` 中的文件
426
+ 3. 添加 `ignores` 模式列表
375
427
  - 模式规范化:自动添加 `**/` 前缀和 `/**` 后缀
376
428
 
377
429
  4. **生成虚拟配置**: 动态生成 `eslint.config.mjs` 内容,包含:
@@ -6,14 +6,6 @@ import reactPlugin from 'eslint-plugin-react';
6
6
  import reactHooksPlugin from 'eslint-plugin-react-hooks';
7
7
 
8
8
  import css from '@eslint/css'
9
-
10
- // ... skipped standard imports ...
11
-
12
- // Removed Patch Mock - No longer needed as we don't use eslint-config-next
13
-
14
- // ...
15
-
16
-
17
9
  import js from '@eslint/js'
18
10
  import json from '@eslint/json'
19
11
  import markdown from '@eslint/markdown'
package/dist/cli.js CHANGED
@@ -17,6 +17,7 @@ cli
17
17
  .option("--level <level>", "Project level (js, ts, frontend, nextjs)")
18
18
  .option("--no-project-type-check", "Disable project-based type checking (faster for single files)")
19
19
  .option("--tsconfig <path>", "Path to tsconfig file for type checking and import resolution")
20
+ .option("--ignore-file [path]", "Add gitignore-style file for ignore patterns (can be used multiple times)")
20
21
  .option("--ignore [pattern]", "Add ignore pattern (can be used multiple times)")
21
22
  .option("--no-ignore", "Disable all ignore rules (including .gitignore)")
22
23
  .option("--cache-dir <dir>", "Custom temporary cache directory")
@@ -59,7 +60,14 @@ cli
59
60
  ? options.ignore.filter((p) => typeof p === 'string')
60
61
  : [options.ignore];
61
62
  }
62
- const temps = await generateTempConfig(cwd, userConfigResult, options.level, options.cacheDir, options.debug, options.projectTypeCheck, options.tsconfig, ignorePatterns, noIgnore);
63
+ // Normalize ignore-file option to array
64
+ let ignoreFiles = [];
65
+ if (!noIgnore && options.ignoreFile && options.ignoreFile !== true) {
66
+ ignoreFiles = Array.isArray(options.ignoreFile)
67
+ ? options.ignoreFile.filter((p) => typeof p === 'string')
68
+ : [options.ignoreFile];
69
+ }
70
+ const temps = await generateTempConfig(cwd, userConfigResult, options.level, options.cacheDir, options.debug, options.projectTypeCheck, options.tsconfig, ignorePatterns, noIgnore, ignoreFiles);
63
71
  usedCachePath = temps.cachePath; // Save for cleanup
64
72
  // 计时:第一阶段(准备阶段)
65
73
  if (showTime) {
package/dist/config.d.ts CHANGED
@@ -23,6 +23,21 @@ export type Config = {
23
23
  */
24
24
  tsconfig?: string;
25
25
  /**
26
+ * List of gitignore-style files to read ignore patterns from.
27
+ * Each file should follow .gitignore syntax.
28
+ * @default ['./.gitignore']
29
+ * @example ['./.gitignore', './.eslintignore']
30
+ */
31
+ ignoreFiles?: string[];
32
+ /**
33
+ * List of specific files or patterns to ignore.
34
+ * Patterns follow glob syntax.
35
+ * @default ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock']
36
+ * @example ['temp', 'generated', '*.test.ts']
37
+ */
38
+ ignores?: string[];
39
+ /**
40
+ * @deprecated Use `ignores` instead. This field will be removed in a future version.
26
41
  * Additional ignore patterns to exclude files from linting.
27
42
  * Patterns follow glob syntax.
28
43
  * @example ['temp', 'generated', '*.test.ts']
@@ -6,7 +6,7 @@ export declare function loadUserConfig(cwd: string): Promise<{
6
6
  export declare function generateTempConfig(cwd: string, userConfigResult: {
7
7
  config: Config;
8
8
  path?: string;
9
- }, cliLevel?: string, cliCacheDir?: string, debug?: boolean, cliProjectTypeCheck?: boolean, cliTsconfig?: string, cliIgnorePatterns?: string[], noIgnore?: boolean): Promise<{
9
+ }, cliLevel?: string, cliCacheDir?: string, debug?: boolean, cliProjectTypeCheck?: boolean, cliTsconfig?: string, cliIgnorePatterns?: string[], noIgnore?: boolean, cliIgnoreFiles?: string[]): Promise<{
10
10
  eslintPath: string;
11
11
  prettierPath: string;
12
12
  cachePath: string;
@@ -50,18 +50,40 @@ export async function loadUserConfig(cwd) {
50
50
  }
51
51
  return { config: {} };
52
52
  }
53
- export async function generateTempConfig(cwd, userConfigResult, cliLevel, cliCacheDir, debug, cliProjectTypeCheck, cliTsconfig, cliIgnorePatterns = [], noIgnore = false) {
53
+ // 默认的忽略文件列表
54
+ const DEFAULT_IGNORE_FILES = ['./.gitignore'];
55
+ // 默认的忽略模式列表
56
+ const DEFAULT_IGNORES = ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock'];
57
+ // 默认始终忽略的目录
58
+ const DEFAULT_IGNORE_DIRS = [
59
+ 'node_modules', 'dist', '.next', '.git', '.output', '.nuxt', 'coverage', '.cache'
60
+ ];
61
+ export async function generateTempConfig(cwd, userConfigResult, cliLevel, cliCacheDir, debug, cliProjectTypeCheck, cliTsconfig, cliIgnorePatterns = [], noIgnore = false, cliIgnoreFiles = []) {
54
62
  const cachePath = getCacheDir(cwd, userConfigResult.config, cliCacheDir);
55
63
  await fs.ensureDir(cachePath);
56
64
  const eslintTempPath = path.join(cachePath, "eslint.config.mjs");
57
65
  const prettierTempPath = path.join(cachePath, "prettier.config.mjs");
58
66
  const metaPath = path.join(cachePath, "metadata.json");
59
- const gitignorePath = path.join(cwd, ".gitignore");
60
67
  // Determine projectTypeCheck: CLI flag takes precedence over config file, default is true
61
68
  // When --no-project-type-check is used, options.projectTypeCheck will be false
62
69
  const projectTypeCheck = cliProjectTypeCheck ?? userConfigResult.config.projectTypeCheck ?? true;
63
70
  // Determine tsconfig path: CLI flag takes precedence over config file
64
71
  const tsconfigPath = cliTsconfig ?? userConfigResult.config.tsconfig;
72
+ // 解析忽略文件列表:CLI 覆盖 config,否则使用 config 或默认值
73
+ // CLI 优先级最高,如果 CLI 有值则完全使用 CLI 的值
74
+ const resolvedIgnoreFiles = cliIgnoreFiles.length > 0
75
+ ? cliIgnoreFiles
76
+ : (userConfigResult.config.ignoreFiles !== undefined
77
+ ? userConfigResult.config.ignoreFiles
78
+ : DEFAULT_IGNORE_FILES);
79
+ // 解析忽略模式列表:CLI 覆盖 config,否则使用 config 或默认值
80
+ // 同时兼容旧的 ignore 字段
81
+ const configIgnores = userConfigResult.config.ignores ?? userConfigResult.config.ignore ?? [];
82
+ const resolvedIgnores = cliIgnorePatterns.length > 0
83
+ ? cliIgnorePatterns
84
+ : (configIgnores.length > 0
85
+ ? configIgnores
86
+ : DEFAULT_IGNORES);
65
87
  let calculatedHash = "";
66
88
  try {
67
89
  const hash = createHash("sha256");
@@ -69,18 +91,23 @@ export async function generateTempConfig(cwd, userConfigResult, cliLevel, cliCac
69
91
  hash.update(cliLevel || "default");
70
92
  hash.update(projectTypeCheck ? "ptc-on" : "ptc-off");
71
93
  hash.update(tsconfigPath || "default-tsconfig");
72
- hash.update(cliIgnorePatterns.join(",") || "no-cli-ignore");
94
+ hash.update(resolvedIgnoreFiles.join(",") || "no-ignore-files");
95
+ hash.update(resolvedIgnores.join(",") || "no-ignores");
73
96
  hash.update(noIgnore ? "no-ignore" : "with-ignore");
74
97
  if (userConfigResult.path && await fs.pathExists(userConfigResult.path)) {
75
98
  const content = await fs.readFile(userConfigResult.path);
76
99
  hash.update(content);
77
100
  }
78
- if (await fs.pathExists(gitignorePath)) {
79
- const content = await fs.readFile(gitignorePath);
80
- hash.update(content);
81
- }
82
- else {
83
- hash.update("no-gitignore");
101
+ // 为每个忽略文件计算 hash
102
+ for (const ignoreFile of resolvedIgnoreFiles) {
103
+ const ignoreFilePath = path.resolve(cwd, ignoreFile);
104
+ if (await fs.pathExists(ignoreFilePath)) {
105
+ const content = await fs.readFile(ignoreFilePath);
106
+ hash.update(content);
107
+ }
108
+ else {
109
+ hash.update(`no-file:${ignoreFile}`);
110
+ }
84
111
  }
85
112
  calculatedHash = hash.digest("hex");
86
113
  if (await fs.pathExists(metaPath)) {
@@ -97,7 +124,7 @@ export async function generateTempConfig(cwd, userConfigResult, cliLevel, cliCac
97
124
  let ignoredPatterns = [];
98
125
  // If --no-ignore is set, skip all ignore processing
99
126
  if (!noIgnore) {
100
- // Parse .gitignore file and convert to ESLint ignore patterns
127
+ // Parse gitignore-style file and convert to ESLint ignore patterns
101
128
  // ESLint ignores are relative to the cwd where ESLint runs (which is the project root)
102
129
  // NOT relative to the config file location
103
130
  const parseGitignore = (content) => {
@@ -159,62 +186,65 @@ export async function generateTempConfig(cwd, userConfigResult, cliLevel, cliCac
159
186
  }
160
187
  return patterns;
161
188
  };
162
- // Default directories to always ignore (relative to project root)
163
- const defaultIgnores = [
164
- 'node_modules', 'dist', '.next', '.git', '.output', '.nuxt', 'coverage', '.cache'
165
- ].map(dir => `**/${dir}/**`);
166
- if (await fs.pathExists(gitignorePath)) {
167
- try {
168
- const gitignoreContent = await fs.readFile(gitignorePath, 'utf-8');
169
- if (debug) {
170
- console.log("-----------------------------------------");
171
- console.log("DEBUG: .gitignore content preview:");
172
- console.log(gitignoreContent.substring(0, 500));
173
- console.log("-----------------------------------------");
189
+ // 规范化忽略模式(添加 **/ 前缀和 /** 后缀)
190
+ const normalizePattern = (pattern) => {
191
+ // If pattern doesn't start with ** or !, add **/ prefix
192
+ if (!pattern.startsWith('**') && !pattern.startsWith('!')) {
193
+ pattern = `**/${pattern}`;
194
+ }
195
+ // If pattern doesn't end with /** and doesn't contain *, add /** suffix
196
+ if (!pattern.endsWith('/**') && !pattern.includes('*')) {
197
+ pattern = `${pattern}/**`;
198
+ }
199
+ return pattern;
200
+ };
201
+ // 1. 添加默认始终忽略的目录
202
+ const defaultDirPatterns = DEFAULT_IGNORE_DIRS.map(dir => `**/${dir}/**`);
203
+ ignoredPatterns.push(...defaultDirPatterns);
204
+ // 2. 解析所有忽略文件
205
+ for (const ignoreFile of resolvedIgnoreFiles) {
206
+ const ignoreFilePath = path.resolve(cwd, ignoreFile);
207
+ if (await fs.pathExists(ignoreFilePath)) {
208
+ try {
209
+ const content = await fs.readFile(ignoreFilePath, 'utf-8');
210
+ if (debug) {
211
+ console.log("-----------------------------------------");
212
+ console.log(`DEBUG: ${ignoreFile} content preview:`);
213
+ console.log(content.substring(0, 500));
214
+ console.log("-----------------------------------------");
215
+ }
216
+ const parsedPatterns = parseGitignore(content);
217
+ if (debug) {
218
+ console.log("-----------------------------------------");
219
+ console.log(`DEBUG: Parsed patterns from ${ignoreFile}:`);
220
+ parsedPatterns.forEach((p, i) => console.log(` [${i}] "${p}"`));
221
+ console.log("-----------------------------------------");
222
+ }
223
+ ignoredPatterns.push(...parsedPatterns);
174
224
  }
175
- const parsedPatterns = parseGitignore(gitignoreContent);
176
- if (debug) {
177
- console.log("-----------------------------------------");
178
- console.log("DEBUG: Parsed gitignore patterns:");
179
- parsedPatterns.forEach((p, i) => console.log(` [${i}] "${p}"`));
180
- console.log("-----------------------------------------");
225
+ catch (e) {
226
+ logger.debug(`Failed to parse ignore file: ${ignoreFile}`, e);
181
227
  }
182
- // Merge defaults with parsed patterns, removing duplicates
183
- const allPatterns = [...defaultIgnores, ...parsedPatterns];
184
- ignoredPatterns = [...new Set(allPatterns)];
185
228
  }
186
- catch (e) {
187
- logger.debug("Failed to parse .gitignore", e);
188
- ignoredPatterns = defaultIgnores;
229
+ else if (debug) {
230
+ console.log(`DEBUG: Ignore file not found: ${ignoreFile}`);
189
231
  }
190
232
  }
191
- else {
192
- ignoredPatterns = defaultIgnores;
193
- }
194
- // Add CLI and config file ignore patterns
195
- const configIgnorePatterns = (userConfigResult.config.ignore || []).filter((p) => typeof p === 'string');
196
- const allCliPatterns = [...cliIgnorePatterns, ...configIgnorePatterns];
197
- if (allCliPatterns.length > 0) {
198
- // Normalize CLI patterns (add **/ prefix and /** suffix if needed)
199
- const normalizedCliPatterns = allCliPatterns.map(pattern => {
200
- // If pattern doesn't start with ** or !, add **/ prefix
201
- if (!pattern.startsWith('**') && !pattern.startsWith('!')) {
202
- pattern = `**/${pattern}`;
203
- }
204
- // If pattern doesn't end with /** and doesn't contain *, add /** suffix
205
- if (!pattern.endsWith('/**') && !pattern.includes('*')) {
206
- pattern = `${pattern}/**`;
207
- }
208
- return pattern;
209
- });
210
- ignoredPatterns = [...new Set([...ignoredPatterns, ...normalizedCliPatterns])];
233
+ // 3. 添加解析后的忽略模式
234
+ if (resolvedIgnores.length > 0) {
235
+ const normalizedPatterns = resolvedIgnores
236
+ .filter((p) => typeof p === 'string')
237
+ .map(normalizePattern);
238
+ ignoredPatterns.push(...normalizedPatterns);
211
239
  if (debug) {
212
240
  console.log("-----------------------------------------");
213
- console.log("DEBUG: CLI/Config ignore patterns added:");
214
- normalizedCliPatterns.forEach((p, i) => console.log(` [${i}] "${p}"`));
241
+ console.log("DEBUG: Resolved ignore patterns:");
242
+ normalizedPatterns.forEach((p, i) => console.log(` [${i}] "${p}"`));
215
243
  console.log("-----------------------------------------");
216
244
  }
217
245
  }
246
+ // 去重
247
+ ignoredPatterns = [...new Set(ignoredPatterns)];
218
248
  }
219
249
  else if (debug) {
220
250
  console.log("-----------------------------------------");
@@ -295,13 +325,15 @@ prefixConfig.push({ ignores: ${JSON.stringify(ignoredPatterns)} });
295
325
  ` : ''}
296
326
 
297
327
  if (${isEslintOverlay} || userEslint.overlay) {
298
- if (Array.isArray(userEslint.config)) {
299
- finalConfig = [...prefixConfig, ...defaultEslint, ...userEslint.config];
328
+ // overlay=true: 用户配置完全覆盖内置配置
329
+ const userConf = userEslint.config || [];
330
+ if (Array.isArray(userConf)) {
331
+ finalConfig = [...prefixConfig, ...userConf];
300
332
  } else {
301
- finalConfig = defu(userEslint, defaultEslint);
302
- if (!Array.isArray(finalConfig)) finalConfig = [...prefixConfig, finalConfig];
333
+ finalConfig = [...prefixConfig, userConf];
303
334
  }
304
335
  } else {
336
+ // overlay=false: 内置配置 + 用户配置追加
305
337
  const userConf = userEslint.config || [];
306
338
  const defaultConf = Array.isArray(defaultEslint) ? defaultEslint : [defaultEslint];
307
339
  finalConfig = [...prefixConfig, ...defaultConf, ...userConf];
@@ -326,8 +358,10 @@ const defaultPrettier = defaultOne;
326
358
 
327
359
  let finalConfig;
328
360
  if (${isPrettierOverlay} || userPrettier.overlay) {
329
- finalConfig = defu(userPrettier.config || {}, defaultPrettier);
361
+ // overlay=true: 用户配置完全覆盖内置配置
362
+ finalConfig = userPrettier.config || {};
330
363
  } else {
364
+ // overlay=false: 内置配置为基础,用户配置补充
331
365
  finalConfig = defu(userPrettier.config || {}, defaultPrettier);
332
366
  }
333
367
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rhine-lint",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "module": "./dist/index.js",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",