@infra-x/create-eslint-config 0.1.4 → 0.2.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.
Files changed (31) hide show
  1. package/dist/index.mjs +8 -10
  2. package/dist/template/.turbo/turbo-build.log +13 -0
  3. package/dist/template/CHANGELOG.md +7 -0
  4. package/dist/template/README.md +95 -1
  5. package/dist/template/eslint.config.mts +1 -2
  6. package/dist/template/package.json +25 -13
  7. package/dist/template/src/configs/a11y.ts +2 -2
  8. package/dist/template/src/configs/better-tailwindcss.ts +3 -3
  9. package/dist/template/src/configs/boundaries.ts +1 -1
  10. package/dist/template/src/configs/depend.ts +3 -4
  11. package/dist/template/src/configs/global-ignores.ts +70 -0
  12. package/dist/template/src/configs/imports.ts +23 -22
  13. package/dist/template/src/configs/javascript.ts +1 -1
  14. package/dist/template/src/configs/jsdoc.ts +1 -1
  15. package/dist/template/src/configs/nextjs.ts +2 -2
  16. package/dist/template/src/configs/oxlint.ts +16 -0
  17. package/dist/template/src/configs/package-json.ts +1 -1
  18. package/dist/template/src/configs/react.ts +16 -7
  19. package/dist/template/src/configs/storybook.ts +1 -1
  20. package/dist/template/src/configs/stylistic.ts +1 -1
  21. package/dist/template/src/configs/typescript.ts +3 -11
  22. package/dist/template/src/configs/unicorn.ts +1 -1
  23. package/dist/template/src/configs/vitest.ts +3 -4
  24. package/dist/template/src/index.ts +59 -73
  25. package/dist/template/src/types.ts +44 -37
  26. package/dist/template/src/utils.ts +17 -17
  27. package/dist/template/tsconfig.json +1 -1
  28. package/package.json +16 -17
  29. package/README.md +0 -14
  30. package/dist/template/src/configs/ignores.ts +0 -78
  31. package/dist/template/src/configs/prettier.ts +0 -25
package/dist/index.mjs CHANGED
@@ -3,24 +3,23 @@ import { access, cp, readdir } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { confirm, intro, log, outro } from "@clack/prompts";
6
-
7
6
  //#region src/index.ts
8
- async function getConflicts(templateDir$1, destDir$1) {
9
- const entries = await readdir(templateDir$1, {
7
+ async function getConflicts(templateDir, destDir) {
8
+ const entries = await readdir(templateDir, {
10
9
  recursive: true,
11
10
  withFileTypes: true
12
11
  });
13
- const conflicts$1 = [];
12
+ const conflicts = [];
14
13
  for (const entry of entries) {
15
14
  if (!entry.isFile()) continue;
16
- const rel = path.join(entry.parentPath, entry.name).slice(templateDir$1.length + 1);
17
- const destPath = path.join(destDir$1, rel);
15
+ const rel = path.join(entry.parentPath, entry.name).slice(templateDir.length + 1);
16
+ const destPath = path.join(destDir, rel);
18
17
  try {
19
18
  await access(destPath);
20
- conflicts$1.push(rel);
19
+ conflicts.push(rel);
21
20
  } catch {}
22
21
  }
23
- return conflicts$1;
22
+ return conflicts;
24
23
  }
25
24
  intro("@infra-x/create-eslint-config");
26
25
  const templateDir = path.join(fileURLToPath(new URL(".", import.meta.url)), "template");
@@ -35,6 +34,5 @@ if (conflicts.length > 0) {
35
34
  }
36
35
  await cp(templateDir, destDir, { recursive: true });
37
36
  outro("复制完成!");
38
-
39
37
  //#endregion
40
- export { };
38
+ export {};
@@ -0,0 +1,13 @@
1
+
2
+ > @infra-x/eslint-config@0.1.6 build /home/runner/work/infra-code/infra-code/packages/eslint-config
3
+ > tsdown
4
+
5
+ ℹ tsdown v0.21.4 powered by rolldown v1.0.0-rc.9
6
+ ℹ config file: /home/runner/work/infra-code/infra-code/packages/eslint-config/tsdown.config.ts
7
+ ℹ entry: src/index.ts
8
+ ℹ tsconfig: tsconfig.json
9
+ ℹ Build start
10
+ ℹ dist/index.mjs 16.72 kB │ gzip: 4.79 kB
11
+ ℹ dist/index.d.mts  7.11 kB │ gzip: 2.31 kB
12
+ ℹ 2 files, total: 23.83 kB
13
+ ✔ Build complete in 1801ms
@@ -0,0 +1,7 @@
1
+ # @infra-x/eslint-config
2
+
3
+ ## 0.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 478b0b3: test changeset flow
@@ -1,3 +1,97 @@
1
1
  # @infra-x/eslint-config
2
2
 
3
- 共享 ESLint flat config 配置工厂。完整使用说明见[根目录 README](../../README.md)。
3
+ Composable ESLint flat config factory for infra-x projects.
4
+
5
+ ## Release
6
+
7
+ ```bash
8
+ pnpm release
9
+ ```
10
+
11
+ 交互式选择版本号,自动 bump `package.json`、提交、打 tag。
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pnpm add -D @infra-x/eslint-config eslint globals
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```typescript
22
+ // eslint.config.mts
23
+ import { composeConfig } from '@infra-x/eslint-config'
24
+
25
+ export default composeConfig({
26
+ typescript: { tsconfigRootDir: import.meta.dirname },
27
+ react: true,
28
+ tailwind: true,
29
+ imports: true,
30
+ })
31
+ ```
32
+
33
+ For multiple config segments (e.g. separate test rules):
34
+
35
+ ```typescript
36
+ // eslint.config.mts
37
+ import { GLOB_TESTS, composeConfig } from '@infra-x/eslint-config'
38
+ import { defineConfig } from 'eslint/config'
39
+
40
+ const appConfig = defineConfig({
41
+ extends: composeConfig({
42
+ typescript: { tsconfigRootDir: import.meta.dirname },
43
+ imports: true,
44
+ react: true,
45
+ nextjs: true,
46
+ }),
47
+ })
48
+
49
+ const vitestConfig = defineConfig({
50
+ files: GLOB_TESTS,
51
+ extends: composeConfig({
52
+ typescript: { tsconfigRootDir: import.meta.dirname },
53
+ vitest: true,
54
+ unicorn: false,
55
+ stylistic: false,
56
+ depend: false,
57
+ }),
58
+ })
59
+
60
+ export default [...appConfig, ...vitestConfig]
61
+ ```
62
+
63
+ Each option accepts `true` (defaults), an options object, or `false` (disable).
64
+
65
+ ## Options
66
+
67
+ Default-on: `globalIgnores` · `javascript` · `typescript` · `stylistic` · `unicorn` · `depend`
68
+
69
+ Opt-in:
70
+
71
+ | Option | Description |
72
+ |---|---|
73
+ | `react` | React + react-hooks rules; set `vite: true` for react-refresh |
74
+ | `nextjs` | Next.js rules |
75
+ | `tailwind` | Tailwind CSS class ordering (`entryPoint` defaults to `src/global.css`) |
76
+ | `imports` | Import ordering and resolution |
77
+ | `a11y` | Accessibility rules |
78
+ | `jsdoc` | JSDoc rules |
79
+ | `boundaries` | Module boundary enforcement |
80
+ | `packageJson` | `package.json` rules |
81
+ | `vitest` | Vitest testing rules |
82
+ | `storybook` | Storybook rules |
83
+ | `oxlint` | Disable ESLint rules already covered by oxlint (requires oxlint to run separately) |
84
+
85
+ All options support an `overrides` field for custom rule overrides, and most accept a `files` glob array.
86
+
87
+ ## Oxlint Integration
88
+
89
+ When running oxlint alongside ESLint, enable the `oxlint` option to disable duplicate rules:
90
+
91
+ ```typescript
92
+ // uses flat/recommended preset
93
+ composeConfig({ oxlint: true })
94
+
95
+ // generate disabled rules from your oxlint config file
96
+ composeConfig({ oxlint: { configFile: './.oxlintrc.json' } })
97
+ ```
@@ -5,9 +5,8 @@ import type { Linter } from 'eslint'
5
5
  const config: Linter.Config[] = composeConfig({
6
6
  typescript: { tsconfigRootDir: import.meta.dirname },
7
7
  imports: {
8
- typescript: true,
9
8
  overrides: {
10
- // 本包内部使用相对导入,因为没有配置路径别名
9
+ // This package uses relative imports internally since no path aliases are configured
11
10
  'no-restricted-imports': 'off',
12
11
  },
13
12
  },
@@ -19,6 +19,7 @@
19
19
  "typecheck": "tsc --noEmit"
20
20
  },
21
21
  "devDependencies": {
22
+ "@infra-x/typescript-config": "0.1.6",
22
23
  "@types/eslint-plugin-jsx-a11y": "^6.10.1",
23
24
  "@types/node": "^25.0.3",
24
25
  "eslint": "^9.39.2",
@@ -30,32 +31,43 @@
30
31
  },
31
32
  "dependencies": {
32
33
  "@eslint-react/eslint-plugin": "^2.13.0",
33
- "@eslint/compat": "1.4.1",
34
+ "@eslint/compat": "2.0.3",
34
35
  "@eslint/core": "0.17.0",
35
- "@eslint/js": "^9.39.3",
36
+ "@eslint/js": "^10.0.1",
36
37
  "@next/eslint-plugin-next": "^16.1.6",
37
38
  "@stylistic/eslint-plugin": "^5.9.0",
38
39
  "@vitest/eslint-plugin": "^1.6.9",
39
40
  "eslint-import-resolver-typescript": "^4.4.4",
40
41
  "eslint-plugin-better-tailwindcss": "^4.3.1",
41
42
  "eslint-plugin-boundaries": "^5.4.0",
42
- "eslint-plugin-depend": "^1.4.0",
43
- "eslint-plugin-import-x": "4.16.1",
44
- "eslint-plugin-jsdoc": "^61.7.1",
43
+ "eslint-plugin-depend": "^1.5.0",
44
+ "eslint-plugin-import-x": "4.16.2",
45
+ "eslint-plugin-jsdoc": "^62.7.1",
45
46
  "eslint-plugin-jsx-a11y": "^6.10.2",
46
- "eslint-plugin-package-json": "^0.64.0",
47
- "eslint-plugin-prettier": "^5.5.5",
47
+ "eslint-plugin-package-json": "^0.91.0",
48
48
  "eslint-plugin-react-hooks": "^7.0.1",
49
- "eslint-plugin-react-refresh": "^0.4.26",
50
- "eslint-plugin-storybook": "^10.2.12",
51
- "eslint-plugin-unicorn": "^57.0.0",
49
+ "eslint-plugin-react-refresh": "^0.5.2",
50
+ "eslint-plugin-oxlint": "^0.16.0",
51
+ "eslint-plugin-storybook": "^10.2.14",
52
+ "eslint-plugin-unicorn": "^63.0.0",
52
53
  "typescript-eslint": "^8.56.1"
53
54
  },
54
55
  "peerDependencies": {
55
- "eslint": "^9.39.2",
56
- "globals": "16.5.0",
56
+ "eslint": "^9.39.2 || ^10.0.0",
57
+ "globals": "17.4.0",
57
58
  "jiti": "2.6.1",
58
- "prettier": "^3.7.4",
59
+ "storybook": ">=10.0.0",
59
60
  "typescript": "^5.9.3"
61
+ },
62
+ "peerDependenciesMeta": {
63
+ "jiti": {
64
+ "optional": true
65
+ },
66
+ "storybook": {
67
+ "optional": true
68
+ },
69
+ "typescript": {
70
+ "optional": true
71
+ }
60
72
  }
61
73
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * eslint-plugin-jsx-a11y 配置,用于检测 JSX 中的无障碍问题(WCAG 标准)
2
+ * eslint-plugin-jsx-a11y configuration for detecting accessibility issues in JSX (WCAG standard)
3
3
  */
4
4
  import { defineConfig } from 'eslint/config'
5
5
  import jsxA11y from 'eslint-plugin-jsx-a11y'
@@ -10,7 +10,7 @@ import type { A11yOptions } from '../types'
10
10
  import type { Linter } from 'eslint'
11
11
 
12
12
  /**
13
- * 可访问性规则配置
13
+ * Accessibility rule configuration
14
14
  */
15
15
  export function a11y(options: A11yOptions = {}): Linter.Config[] {
16
16
  const { files = [GLOB_JSX], overrides = {} } = options
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tailwind CSS ESLint 配置,使用官方推荐规则集
2
+ * Tailwind CSS ESLint configuration using the official recommended ruleset
3
3
  */
4
4
  import { defineConfig } from 'eslint/config'
5
5
  import eslintPluginBetterTailwindcss from 'eslint-plugin-better-tailwindcss'
@@ -10,10 +10,10 @@ import type { TailwindOptions } from '../types'
10
10
  import type { Linter } from 'eslint'
11
11
 
12
12
  /**
13
- * Tailwind CSS 规则配置
13
+ * Tailwind CSS rule configuration
14
14
  */
15
15
  export function tailwind(options: TailwindOptions = {}): Linter.Config[] {
16
- const { files = [GLOB_JSX], overrides = {}, entryPoint = 'src/global.css' } = options
16
+ const { files = [GLOB_JSX], overrides = {}, entryPoint = 'src/styles/global.css' } = options
17
17
 
18
18
  return defineConfig({
19
19
  name: 'tailwind/rules',
@@ -1,5 +1,5 @@
1
1
  /**
2
- * eslint-plugin-boundaries 配置,用于强制执行架构边界规则
2
+ * eslint-plugin-boundaries configuration for enforcing architectural boundary rules
3
3
  */
4
4
  import { defineConfig } from 'eslint/config'
5
5
  import boundariesPlugin from 'eslint-plugin-boundaries'
@@ -1,13 +1,12 @@
1
1
  /**
2
- * 依赖优化规则配置,检测可用原生 API 替代的包和微型工具库
2
+ * Dependency optimization rule configuration for detecting packages replaceable with native APIs or micro-utilities
3
3
  */
4
- import { fixupPluginRules } from '@eslint/compat'
5
4
  import dependPlugin from 'eslint-plugin-depend'
6
5
 
7
6
  import { GLOB_SRC } from '../utils'
8
7
 
9
8
  import type { DependOptions } from '../types'
10
- import type { ESLint, Linter } from 'eslint'
9
+ import type { Linter } from 'eslint'
11
10
 
12
11
  const DEFAULT_PRESETS: DependOptions['presets'] = ['native', 'microutilities', 'preferred']
13
12
 
@@ -19,7 +18,7 @@ export function depend(options: DependOptions = {}): Linter.Config[] {
19
18
  name: 'depend/rules',
20
19
  files: [GLOB_SRC],
21
20
  plugins: {
22
- depend: fixupPluginRules(dependPlugin as unknown as ESLint.Plugin),
21
+ depend: dependPlugin,
23
22
  },
24
23
  rules: {
25
24
  'depend/ban-dependencies': [
@@ -0,0 +1,70 @@
1
+ /**
2
+ * ESLint ignore configuration with built-in default ignore patterns and .gitignore integration
3
+ */
4
+ import { existsSync, readFileSync } from 'node:fs'
5
+ import path from 'node:path'
6
+
7
+ import { convertIgnorePatternToMinimatch } from '@eslint/compat'
8
+ import { defineConfig, globalIgnores } from 'eslint/config'
9
+
10
+ import type { IgnoresOptions } from '../types'
11
+ import type { Linter } from 'eslint'
12
+
13
+ export const DEFAULT_IGNORES: string[] = [
14
+ // Dependency directories
15
+ '**/node_modules/**',
16
+ '**/.pnp.*',
17
+
18
+ // Build artifacts
19
+ '**/dist/**',
20
+ '**/build/**',
21
+ '**/out/**',
22
+ '**/.next/**',
23
+
24
+ // Cache directories
25
+ '**/.cache/**',
26
+ '**/.turbo/**',
27
+ '**/.eslintcache',
28
+
29
+ // Version control
30
+ '**/.git/**',
31
+ '**/.svn/**',
32
+ '**/.hg/**',
33
+ '**/public/**',
34
+
35
+ // Type declaration files
36
+ '**/*.d.ts',
37
+ ]
38
+
39
+ export function ignores(options: IgnoresOptions = {}): Linter.Config[] {
40
+ const { ignores: userIgnores, gitignore = true } = options
41
+
42
+ if (userIgnores === false) {
43
+ return []
44
+ }
45
+
46
+ const gitignorePatterns: string[] = []
47
+ if (gitignore) {
48
+ const gitignoreFile = path.resolve(process.cwd(), '.gitignore')
49
+ if (existsSync(gitignoreFile)) {
50
+ const lines = readFileSync(gitignoreFile, 'utf8').split(/\r?\n/u)
51
+ gitignorePatterns.push(
52
+ ...lines
53
+ .map((line) => line.trim())
54
+ .filter((line) => line && !line.startsWith('#'))
55
+ .map((line) => convertIgnorePatternToMinimatch(line)),
56
+ )
57
+ }
58
+ }
59
+
60
+ const userPatterns = userIgnores
61
+ ? (Array.isArray(userIgnores) ? userIgnores : [userIgnores])
62
+ : []
63
+
64
+ return defineConfig([
65
+ globalIgnores(
66
+ [...DEFAULT_IGNORES, ...gitignorePatterns, ...userPatterns],
67
+ 'ignores/globals/defaults',
68
+ ),
69
+ ])
70
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Import 模块导入规则配置,提供导入排序、循环依赖检测和 TypeScript 支持
2
+ * Import rule configuration providing import ordering, circular dependency detection, and TypeScript support
3
3
  */
4
4
  import { defineConfig } from 'eslint/config'
5
5
  import { importX } from 'eslint-plugin-import-x'
@@ -10,14 +10,19 @@ import type { ImportsOptions } from '../types'
10
10
  import type { ESLint, Linter } from 'eslint'
11
11
 
12
12
  export function imports(options: ImportsOptions = {}): Linter.Config[] {
13
- const { overrides = {}, stylistic = true, typescript = false, noRelativeParentImports = false } = options
13
+ const { overrides = {}, typescript = false, noRelativeParentImports = false, tsconfigRootDir } = options
14
14
 
15
15
  const files = [GLOB_SRC]
16
16
 
17
17
  const settingsForTypescript = typescript
18
18
  ? {
19
19
  ...importX.configs['flat/recommended'].settings,
20
- 'import-x/resolver': { typescript: { alwaysTryTypes: true } },
20
+ 'import-x/resolver': {
21
+ typescript: {
22
+ alwaysTryTypes: true,
23
+ ...(tsconfigRootDir && { project: tsconfigRootDir }),
24
+ },
25
+ },
21
26
  }
22
27
  : {}
23
28
 
@@ -32,8 +37,17 @@ export function imports(options: ImportsOptions = {}): Linter.Config[] {
32
37
  }
33
38
  : {}
34
39
 
35
- const rulesForStylistic: Record<string, Linter.RuleEntry> = stylistic
36
- ? {
40
+ return defineConfig([
41
+ {
42
+ name: 'imports/rules',
43
+ files,
44
+ plugins: {
45
+ 'import-x': importX as unknown as ESLint.Plugin,
46
+ },
47
+ settings: settingsForTypescript,
48
+ rules: {
49
+ ...importX.configs['flat/recommended'].rules,
50
+ ...rulesForTypescript,
37
51
  'import-x/newline-after-import': ['error', { count: 1 }],
38
52
  'import-x/order': [
39
53
  'error',
@@ -62,25 +76,12 @@ export function imports(options: ImportsOptions = {}): Linter.Config[] {
62
76
  'distinctGroup': true,
63
77
  },
64
78
  ],
65
- }
66
- : {}
67
-
68
- return defineConfig([
69
- {
70
- name: 'imports/rules',
71
- files,
72
- plugins: {
73
- 'import-x': importX as unknown as ESLint.Plugin,
74
- },
75
- settings: settingsForTypescript,
76
- rules: {
77
- ...importX.configs['flat/recommended'].rules,
78
- ...rulesForTypescript,
79
- ...rulesForStylistic,
80
79
  'import-x/consistent-type-specifier-style': 'error',
81
80
  'import-x/no-named-as-default': 'warn',
82
- 'import-x/no-cycle': 'error',
83
- 'import-x/no-unused-modules': 'error',
81
+ // maxDepth 避免全图遍历导致性能问题
82
+ 'import-x/no-cycle': ['error', { maxDepth: 5 }],
83
+ // ignoreExports 防止入口文件的导出被误报为未使用
84
+ 'import-x/no-unused-modules': ['error', { unusedExports: true, ignoreExports: ['**/index.ts', '**/index.tsx'] }],
84
85
  'import-x/no-deprecated': 'warn',
85
86
  'import-x/no-extraneous-dependencies': 'error',
86
87
  'import-x/no-relative-parent-imports': noRelativeParentImports ? 'error' : 'off',
@@ -1,5 +1,5 @@
1
1
  /**
2
- * JavaScript ESLint 基础配置,提供推荐规则和 ES2026+ 全局变量支持
2
+ * JavaScript ESLint base configuration with recommended rules and ES2026+ global variable support
3
3
  */
4
4
  import js from '@eslint/js'
5
5
  import { defineConfig } from 'eslint/config'
@@ -1,5 +1,5 @@
1
1
  /**
2
- * JSDoc 注释规范配置,使用 TypeScript 优化的推荐规则验证注释正确性
2
+ * JSDoc comment validation configuration using TypeScript-optimized recommended rules
3
3
  */
4
4
  import { defineConfig } from 'eslint/config'
5
5
  import jsdocPlugin from 'eslint-plugin-jsdoc'
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Next.js ESLint 配置,使用官方插件检测 Next.js 最佳实践和 Core Web Vitals 性能优化
2
+ * Next.js ESLint configuration using the official plugin for best practices and Core Web Vitals enforcement
3
3
  */
4
4
  import nextjsPlugin from '@next/eslint-plugin-next'
5
5
  import { defineConfig } from 'eslint/config'
@@ -11,7 +11,7 @@ const recommended = nextjsPlugin.configs.recommended as unknown as Linter.Config
11
11
  const coreWebVitals = nextjsPlugin.configs['core-web-vitals'] as unknown as Linter.Config
12
12
 
13
13
  /**
14
- * Next.js 规则配置
14
+ * Next.js rule configuration
15
15
  */
16
16
  export function nextjs(options: NextjsOptions = {}): Linter.Config[] {
17
17
  const { overrides = {} } = options
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Oxlint integration — disables ESLint rules already covered by oxlint
3
+ * to avoid duplicate checking when running both linters in parallel.
4
+ */
5
+ import oxlint from 'eslint-plugin-oxlint'
6
+
7
+ import type { OxlintOptions } from '../types'
8
+ import type { Linter } from 'eslint'
9
+
10
+ export function oxlintConfig(options: OxlintOptions = {}): Linter.Config[] {
11
+ const { configFile } = options
12
+
13
+ return configFile
14
+ ? oxlint.buildFromOxlintConfigFile(configFile)
15
+ : [...oxlint.configs['flat/recommended']]
16
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Package.json 文件规则配置,检查文件一致性、字段验证和依赖管理
2
+ * package.json rule configuration for file consistency checks, field validation, and dependency management
3
3
  */
4
4
  import { defineConfig } from 'eslint/config'
5
5
  import plugin from 'eslint-plugin-package-json'
@@ -1,9 +1,9 @@
1
1
  /**
2
- * React ESLint 配置,集成 @eslint-reactreact-hooks react-refresh 插件
2
+ * React ESLint configuration integrating @eslint-react, react-hooks, and react-refresh plugins
3
3
  */
4
4
  import reactPlugin from '@eslint-react/eslint-plugin'
5
5
  import { defineConfig } from 'eslint/config'
6
- import reactHooksPlugin from 'eslint-plugin-react-hooks'
6
+ // import reactHooksPlugin from 'eslint-plugin-react-hooks'// reactPlugin 新版本已经包含了 reactHooksPlugin
7
7
  import reactRefresh from 'eslint-plugin-react-refresh'
8
8
 
9
9
  import { GLOB_JSX } from '../utils'
@@ -12,20 +12,29 @@ import type { ReactOptions } from '../types'
12
12
  import type { Linter } from 'eslint'
13
13
 
14
14
  /**
15
- * React 规则配置
15
+ * React rule configuration
16
16
  */
17
17
  export function react(options: ReactOptions = {}): Linter.Config[] {
18
- const { files = [GLOB_JSX], overrides = {} } = options
18
+ const { files = [GLOB_JSX], overrides = {}, vite = false } = options
19
19
 
20
20
  return defineConfig({
21
21
  name: 'react/rules',
22
22
  files,
23
23
  extends: [
24
- reactPlugin.configs['recommended-typescript'],
25
- reactHooksPlugin.configs.flat['recommended-latest'],
26
- reactRefresh.configs.recommended,
24
+ reactPlugin.configs['recommended-type-checked'],
25
+ // reactHooksPlugin.configs.flat['recommended-latest'],
26
+ ...(vite ? [reactRefresh.configs.recommended] : []),
27
27
  ],
28
28
  rules: {
29
+ // attributes: false 允许在 JSX 事件属性(如 onClick)上传入 async 函数,此场景仅在 React 中存在
30
+ '@typescript-eslint/no-misused-promises': [
31
+ 'error',
32
+ {
33
+ checksVoidReturn: {
34
+ attributes: false,
35
+ },
36
+ },
37
+ ],
29
38
  ...overrides,
30
39
  },
31
40
  })
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Storybook ESLint 配置,使用官方插件检测 Storybook 最佳实践
2
+ * Storybook ESLint configuration using the official plugin for best practices enforcement
3
3
  */
4
4
  import { defineConfig } from 'eslint/config'
5
5
  import storybookPlugin from 'eslint-plugin-storybook'
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Stylistic 代码风格配置,提供缩进、引号、逗号等格式化规则
2
+ * Stylistic code style configuration providing formatting rules for indentation, quotes, commas, and more
3
3
  */
4
4
  import stylisticPlugin from '@stylistic/eslint-plugin'
5
5
  import { defineConfig } from 'eslint/config'
@@ -1,5 +1,5 @@
1
1
  /**
2
- * TypeScript ESLint 配置,提供类型感知的代码检查(推荐规则 + 风格规则)
2
+ * TypeScript ESLint configuration with type-aware linting (recommended rules + stylistic rules)
3
3
  */
4
4
  import { defineConfig } from 'eslint/config'
5
5
  import { configs, parser, plugin } from 'typescript-eslint'
@@ -10,7 +10,7 @@ import type { TypeScriptOptions } from '../types'
10
10
  import type { Linter } from 'eslint'
11
11
 
12
12
  /**
13
- * TypeScript 规则配置
13
+ * TypeScript rule configuration
14
14
  */
15
15
  export function typescript(options: TypeScriptOptions = {}): Linter.Config[] {
16
16
  const { files = [GLOB_TS], tsconfigRootDir, overrides = {} } = options
@@ -34,16 +34,8 @@ export function typescript(options: TypeScriptOptions = {}): Linter.Config[] {
34
34
  '@typescript-eslint/consistent-type-imports': 'error',
35
35
  '@typescript-eslint/no-unused-vars': 'off',
36
36
  '@typescript-eslint/no-deprecated': 'warn',
37
- '@typescript-eslint/no-inferrable-types': 'off',
37
+ // '@typescript-eslint/no-inferrable-types': 'off', 会导致冗余的类型注解
38
38
  '@typescript-eslint/unbound-method': 'warn',
39
- '@typescript-eslint/no-misused-promises': [
40
- 'error',
41
- {
42
- checksVoidReturn: {
43
- attributes: false,
44
- },
45
- },
46
- ],
47
39
 
48
40
  ...overrides,
49
41
  },
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Unicorn ESLint 配置,提供 100+ 强大规则改进代码质量和一致性
2
+ * Unicorn ESLint configuration providing 100+ powerful rules to improve code quality and consistency
3
3
  */
4
4
  import { defineConfig } from 'eslint/config'
5
5
  import eslintPluginUnicorn from 'eslint-plugin-unicorn'
@@ -1,14 +1,13 @@
1
1
  /**
2
- * Vitest 测试规则配置,包含测试最佳实践和质量保证规则
2
+ * Vitest test rule configuration with testing best practices and quality assurance rules
3
3
  */
4
- import { fixupPluginRules } from '@eslint/compat'
5
4
  import vitestPlugin from '@vitest/eslint-plugin'
6
5
  import { defineConfig } from 'eslint/config'
7
6
 
8
7
  import { GLOB_TESTS, isInEditorEnv } from '../utils'
9
8
 
10
9
  import type { VitestOptions } from '../types'
11
- import type { ESLint, Linter } from 'eslint'
10
+ import type { Linter } from 'eslint'
12
11
 
13
12
  export function vitest(options: VitestOptions = {}): Linter.Config[] {
14
13
  const {
@@ -22,7 +21,7 @@ export function vitest(options: VitestOptions = {}): Linter.Config[] {
22
21
  name: 'vitest/rules',
23
22
  files,
24
23
  plugins: {
25
- vitest: fixupPluginRules(vitestPlugin as unknown as ESLint.Plugin),
24
+ vitest: vitestPlugin,
26
25
  },
27
26
  rules: {
28
27
  ...vitestPlugin.configs.recommended.rules,