@infra-x/create-eslint-config 0.2.0 → 0.2.2
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/dist/template/.turbo/turbo-build.log +6 -6
- package/dist/template/README.md +20 -7
- package/dist/template/eslint.config.mts +0 -1
- package/dist/template/package.json +4 -9
- package/dist/template/src/configs/better-tailwindcss.ts +1 -1
- package/dist/template/src/configs/global-ignores.ts +70 -0
- package/dist/template/src/configs/imports.ts +14 -20
- package/dist/template/src/configs/oxlint.ts +16 -0
- package/dist/template/src/configs/react.ts +12 -3
- package/dist/template/src/configs/typescript.ts +1 -9
- package/dist/template/src/index.ts +17 -36
- package/dist/template/src/types.ts +14 -18
- package/package.json +5 -3
- package/README.md +0 -14
- package/dist/template/src/configs/ignores.ts +0 -78
- package/dist/template/src/configs/prettier.ts +0 -25
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
|
|
2
|
-
> @infra-x/eslint-config@0.1.
|
|
2
|
+
> @infra-x/eslint-config@0.1.8 build /home/runner/work/infra-code/infra-code/packages/eslint-config
|
|
3
3
|
> tsdown
|
|
4
4
|
|
|
5
|
-
[34mℹ[39m tsdown [2mv0.21.
|
|
5
|
+
[34mℹ[39m tsdown [2mv0.21.4[22m powered by rolldown [2mv1.0.0-rc.9[22m
|
|
6
6
|
[34mℹ[39m config file: [4m/home/runner/work/infra-code/infra-code/packages/eslint-config/tsdown.config.ts[24m
|
|
7
7
|
[34mℹ[39m entry: [34msrc/index.ts[39m
|
|
8
8
|
[34mℹ[39m tsconfig: [34mtsconfig.json[39m
|
|
9
9
|
[34mℹ[39m Build start
|
|
10
|
-
[34mℹ[39m [2mdist/[22m[1mindex.mjs[22m [
|
|
11
|
-
[34mℹ[39m [2mdist/[22m[32m[1mindex.d.mts[22m[39m [2m
|
|
12
|
-
[34mℹ[39m 2 files, total:
|
|
13
|
-
[32m✔[39m Build complete in [
|
|
10
|
+
[34mℹ[39m [2mdist/[22m[1mindex.mjs[22m [2m16.59 kB[22m [2m│ gzip: 4.75 kB[22m
|
|
11
|
+
[34mℹ[39m [2mdist/[22m[32m[1mindex.d.mts[22m[39m [2m 7.11 kB[22m [2m│ gzip: 2.31 kB[22m
|
|
12
|
+
[34mℹ[39m 2 files, total: 23.70 kB
|
|
13
|
+
[32m✔[39m Build complete in [32m1852ms[39m
|
package/dist/template/README.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Composable ESLint flat config factory for infra-x projects.
|
|
4
4
|
|
|
5
|
+
## Release
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm release
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
交互式选择版本号,自动 bump `package.json`、提交、打 tag。
|
|
12
|
+
|
|
5
13
|
## Installation
|
|
6
14
|
|
|
7
15
|
```bash
|
|
@@ -19,14 +27,11 @@ export default composeConfig({
|
|
|
19
27
|
react: true,
|
|
20
28
|
tailwind: true,
|
|
21
29
|
imports: true,
|
|
22
|
-
prettier: true,
|
|
23
30
|
})
|
|
24
31
|
```
|
|
25
32
|
|
|
26
33
|
For multiple config segments (e.g. separate test rules):
|
|
27
34
|
|
|
28
|
-
> 注意:在多`tsconfig`配置时,`tsc -b`,需要添加 `-b`参数。
|
|
29
|
-
|
|
30
35
|
```typescript
|
|
31
36
|
// eslint.config.mts
|
|
32
37
|
import { GLOB_TESTS, composeConfig } from '@infra-x/eslint-config'
|
|
@@ -59,7 +64,7 @@ Each option accepts `true` (defaults), an options object, or `false` (disable).
|
|
|
59
64
|
|
|
60
65
|
## Options
|
|
61
66
|
|
|
62
|
-
Default-on: `
|
|
67
|
+
Default-on: `globalIgnores` · `javascript` · `typescript` · `stylistic` · `unicorn` · `depend`
|
|
63
68
|
|
|
64
69
|
Opt-in:
|
|
65
70
|
|
|
@@ -69,16 +74,24 @@ Opt-in:
|
|
|
69
74
|
| `nextjs` | Next.js rules |
|
|
70
75
|
| `tailwind` | Tailwind CSS class ordering (`entryPoint` defaults to `src/global.css`) |
|
|
71
76
|
| `imports` | Import ordering and resolution |
|
|
72
|
-
| `prettier` | Prettier formatting (should be last) |
|
|
73
77
|
| `a11y` | Accessibility rules |
|
|
74
78
|
| `jsdoc` | JSDoc rules |
|
|
75
79
|
| `boundaries` | Module boundary enforcement |
|
|
76
80
|
| `packageJson` | `package.json` rules |
|
|
77
81
|
| `vitest` | Vitest testing rules |
|
|
78
82
|
| `storybook` | Storybook rules |
|
|
83
|
+
| `oxlint` | Disable ESLint rules already covered by oxlint (requires oxlint to run separately) |
|
|
79
84
|
|
|
80
85
|
All options support an `overrides` field for custom rule overrides, and most accept a `files` glob array.
|
|
81
86
|
|
|
82
|
-
##
|
|
87
|
+
## Oxlint Integration
|
|
88
|
+
|
|
89
|
+
When running oxlint alongside ESLint, enable the `oxlint` option to disable duplicate rules:
|
|
83
90
|
|
|
84
|
-
|
|
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,7 +5,6 @@ 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',
|
|
@@ -31,13 +31,12 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@eslint-react/eslint-plugin": "^2.13.0",
|
|
34
|
-
"@eslint/compat": "
|
|
34
|
+
"@eslint/compat": "2.0.3",
|
|
35
35
|
"@eslint/core": "0.17.0",
|
|
36
36
|
"@eslint/js": "^10.0.1",
|
|
37
37
|
"@next/eslint-plugin-next": "^16.1.6",
|
|
38
38
|
"@stylistic/eslint-plugin": "^5.9.0",
|
|
39
39
|
"@vitest/eslint-plugin": "^1.6.9",
|
|
40
|
-
"eslint-config-prettier": "^10.1.8",
|
|
41
40
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
42
41
|
"eslint-plugin-better-tailwindcss": "^4.3.1",
|
|
43
42
|
"eslint-plugin-boundaries": "^5.4.0",
|
|
@@ -46,18 +45,17 @@
|
|
|
46
45
|
"eslint-plugin-jsdoc": "^62.7.1",
|
|
47
46
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
48
47
|
"eslint-plugin-package-json": "^0.91.0",
|
|
49
|
-
"eslint-plugin-prettier": "^5.5.5",
|
|
50
48
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
51
49
|
"eslint-plugin-react-refresh": "^0.5.2",
|
|
50
|
+
"eslint-plugin-oxlint": "^0.18.0",
|
|
52
51
|
"eslint-plugin-storybook": "^10.2.14",
|
|
53
52
|
"eslint-plugin-unicorn": "^63.0.0",
|
|
54
53
|
"typescript-eslint": "^8.56.1"
|
|
55
54
|
},
|
|
56
55
|
"peerDependencies": {
|
|
57
|
-
"eslint": "^9.39.2",
|
|
58
|
-
"globals": "
|
|
56
|
+
"eslint": "^9.39.2 || ^10.0.0",
|
|
57
|
+
"globals": "17.4.0",
|
|
59
58
|
"jiti": "2.6.1",
|
|
60
|
-
"prettier": "^3.7.4",
|
|
61
59
|
"storybook": ">=10.0.0",
|
|
62
60
|
"typescript": "^5.9.3"
|
|
63
61
|
},
|
|
@@ -65,9 +63,6 @@
|
|
|
65
63
|
"jiti": {
|
|
66
64
|
"optional": true
|
|
67
65
|
},
|
|
68
|
-
"prettier": {
|
|
69
|
-
"optional": true
|
|
70
|
-
},
|
|
71
66
|
"storybook": {
|
|
72
67
|
"optional": true
|
|
73
68
|
},
|
|
@@ -13,7 +13,7 @@ import type { Linter } from 'eslint'
|
|
|
13
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',
|
|
@@ -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
|
+
}
|
|
@@ -10,7 +10,7 @@ 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 = {},
|
|
13
|
+
const { overrides = {}, typescript = false, noRelativeParentImports = false, tsconfigRootDir } = options
|
|
14
14
|
|
|
15
15
|
const files = [GLOB_SRC]
|
|
16
16
|
|
|
@@ -37,8 +37,17 @@ export function imports(options: ImportsOptions = {}): Linter.Config[] {
|
|
|
37
37
|
}
|
|
38
38
|
: {}
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
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,
|
|
42
51
|
'import-x/newline-after-import': ['error', { count: 1 }],
|
|
43
52
|
'import-x/order': [
|
|
44
53
|
'error',
|
|
@@ -67,25 +76,10 @@ export function imports(options: ImportsOptions = {}): Linter.Config[] {
|
|
|
67
76
|
'distinctGroup': true,
|
|
68
77
|
},
|
|
69
78
|
],
|
|
70
|
-
}
|
|
71
|
-
: {}
|
|
72
|
-
|
|
73
|
-
return defineConfig([
|
|
74
|
-
{
|
|
75
|
-
name: 'imports/rules',
|
|
76
|
-
files,
|
|
77
|
-
plugins: {
|
|
78
|
-
'import-x': importX as unknown as ESLint.Plugin,
|
|
79
|
-
},
|
|
80
|
-
settings: settingsForTypescript,
|
|
81
|
-
rules: {
|
|
82
|
-
...importX.configs['flat/recommended'].rules,
|
|
83
|
-
...rulesForTypescript,
|
|
84
|
-
...rulesForStylistic,
|
|
85
79
|
'import-x/consistent-type-specifier-style': 'error',
|
|
86
80
|
'import-x/no-named-as-default': 'warn',
|
|
87
|
-
|
|
88
|
-
'import-x/no-
|
|
81
|
+
// maxDepth 避免全图遍历导致性能问题
|
|
82
|
+
'import-x/no-cycle': ['error', { maxDepth: 5 }],
|
|
89
83
|
'import-x/no-deprecated': 'warn',
|
|
90
84
|
'import-x/no-extraneous-dependencies': 'error',
|
|
91
85
|
'import-x/no-relative-parent-imports': noRelativeParentImports ? 'error' : 'off',
|
|
@@ -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
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
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'
|
|
@@ -21,11 +21,20 @@ export function react(options: ReactOptions = {}): Linter.Config[] {
|
|
|
21
21
|
name: 'react/rules',
|
|
22
22
|
files,
|
|
23
23
|
extends: [
|
|
24
|
-
reactPlugin.configs['recommended-
|
|
25
|
-
reactHooksPlugin.configs.flat['recommended-latest'],
|
|
24
|
+
reactPlugin.configs['recommended-type-checked'],
|
|
25
|
+
// reactHooksPlugin.configs.flat['recommended-latest'],
|
|
26
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
|
})
|
|
@@ -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
|
},
|
|
@@ -12,25 +12,21 @@
|
|
|
12
12
|
* react: true,
|
|
13
13
|
* tailwind: true,
|
|
14
14
|
* imports: { typescript: true },
|
|
15
|
-
* prettier: true,
|
|
16
15
|
* })
|
|
17
16
|
* ```
|
|
18
17
|
*/
|
|
19
18
|
|
|
20
|
-
import { defineConfig } from 'eslint/config'
|
|
21
|
-
import { configs as tsConfigs, parser as tsParser } from 'typescript-eslint'
|
|
22
|
-
|
|
23
19
|
import { a11y } from './configs/a11y'
|
|
24
20
|
import { tailwind } from './configs/better-tailwindcss'
|
|
25
21
|
import { boundaries } from './configs/boundaries'
|
|
26
22
|
import { depend } from './configs/depend'
|
|
27
|
-
import { ignores } from './configs/ignores'
|
|
23
|
+
import { ignores } from './configs/global-ignores'
|
|
28
24
|
import { imports } from './configs/imports'
|
|
29
25
|
import { javascript } from './configs/javascript'
|
|
30
26
|
import { jsdoc } from './configs/jsdoc'
|
|
31
27
|
import { nextjs } from './configs/nextjs'
|
|
28
|
+
import { oxlintConfig } from './configs/oxlint'
|
|
32
29
|
import { packageJson } from './configs/package-json'
|
|
33
|
-
import { prettier } from './configs/prettier'
|
|
34
30
|
import { react } from './configs/react'
|
|
35
31
|
import { storybook } from './configs/storybook'
|
|
36
32
|
import { stylistic } from './configs/stylistic'
|
|
@@ -47,8 +43,8 @@ import type {
|
|
|
47
43
|
JavaScriptOptions,
|
|
48
44
|
JsdocOptions,
|
|
49
45
|
NextjsOptions,
|
|
46
|
+
OxlintOptions,
|
|
50
47
|
PackageJsonOptions,
|
|
51
|
-
PrettierOptions,
|
|
52
48
|
ReactOptions,
|
|
53
49
|
StorybookOptions,
|
|
54
50
|
StylisticOptions,
|
|
@@ -75,7 +71,7 @@ import type { Linter } from 'eslint'
|
|
|
75
71
|
export interface ComposeConfigOptions {
|
|
76
72
|
// Base configuration (enabled by default)
|
|
77
73
|
/** Ignore patterns configuration @default true */
|
|
78
|
-
|
|
74
|
+
globalIgnores?: boolean | IgnoresOptions
|
|
79
75
|
/** JavaScript base configuration @default true */
|
|
80
76
|
javascript?: boolean | JavaScriptOptions
|
|
81
77
|
/** TypeScript configuration @default true */
|
|
@@ -86,9 +82,6 @@ export interface ComposeConfigOptions {
|
|
|
86
82
|
unicorn?: boolean | UnicornOptions
|
|
87
83
|
/** Dependency optimization suggestions @default true */
|
|
88
84
|
depend?: boolean | DependOptions
|
|
89
|
-
/** Rules for config files (*.config.ts) without type-checking @default true */
|
|
90
|
-
configFiles?: boolean
|
|
91
|
-
|
|
92
85
|
// Framework configuration
|
|
93
86
|
/** React configuration */
|
|
94
87
|
react?: boolean | ReactOptions
|
|
@@ -100,8 +93,6 @@ export interface ComposeConfigOptions {
|
|
|
100
93
|
// Tooling configuration
|
|
101
94
|
/** Import ordering and rules */
|
|
102
95
|
imports?: boolean | ImportsOptions
|
|
103
|
-
/** Prettier formatting */
|
|
104
|
-
prettier?: boolean | PrettierOptions
|
|
105
96
|
|
|
106
97
|
// Quality configuration
|
|
107
98
|
/** Accessibility rules */
|
|
@@ -118,6 +109,15 @@ export interface ComposeConfigOptions {
|
|
|
118
109
|
vitest?: boolean | VitestOptions
|
|
119
110
|
/** Storybook rules */
|
|
120
111
|
storybook?: boolean | StorybookOptions
|
|
112
|
+
|
|
113
|
+
// Linter integration
|
|
114
|
+
/**
|
|
115
|
+
* Disable ESLint rules already covered by oxlint.
|
|
116
|
+
* Requires oxlint to be run separately.
|
|
117
|
+
* - `true` uses the `flat/recommended` preset
|
|
118
|
+
* - `{ configFile }` generates disabled rules from your oxlint config file
|
|
119
|
+
*/
|
|
120
|
+
oxlint?: boolean | OxlintOptions
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
// ============================================================================
|
|
@@ -137,7 +137,7 @@ type ConfigEntry = {
|
|
|
137
137
|
|
|
138
138
|
const CONFIG_REGISTRY: ConfigEntry[] = [
|
|
139
139
|
// Enabled by default
|
|
140
|
-
{ key: '
|
|
140
|
+
{ key: 'globalIgnores', fn: ignores, defaultOn: true },
|
|
141
141
|
{ key: 'javascript', fn: javascript, defaultOn: true },
|
|
142
142
|
{
|
|
143
143
|
key: 'typescript',
|
|
@@ -167,7 +167,7 @@ const CONFIG_REGISTRY: ConfigEntry[] = [
|
|
|
167
167
|
{ key: 'packageJson', fn: packageJson },
|
|
168
168
|
{ key: 'vitest', fn: vitest },
|
|
169
169
|
{ key: 'storybook', fn: storybook },
|
|
170
|
-
{ key: '
|
|
170
|
+
{ key: 'oxlint', fn: oxlintConfig },
|
|
171
171
|
]
|
|
172
172
|
|
|
173
173
|
/** Composes ESLint configs in the correct internal order */
|
|
@@ -184,26 +184,7 @@ export function composeConfig(options: ComposeConfigOptions = {}): Linter.Config
|
|
|
184
184
|
configs.push(...fn({ ...injected, ...base }))
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
return
|
|
188
|
-
? configs
|
|
189
|
-
: defineConfig([
|
|
190
|
-
{
|
|
191
|
-
ignores: ['*.config.ts', '*.config.mts'],
|
|
192
|
-
extends: [configs],
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
name: 'typescript/config-files',
|
|
196
|
-
files: ['*.config.ts', '*.config.mts'],
|
|
197
|
-
extends: [tsConfigs.recommended],
|
|
198
|
-
languageOptions: {
|
|
199
|
-
parser: tsParser,
|
|
200
|
-
parserOptions: {
|
|
201
|
-
project: false,
|
|
202
|
-
tsconfigRootDir: (typeof options.typescript === 'object' ? options.typescript.tsconfigRootDir : undefined) ?? process.cwd(),
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
])
|
|
187
|
+
return configs
|
|
207
188
|
}
|
|
208
189
|
|
|
209
190
|
// ============================================================================
|
|
@@ -219,8 +200,8 @@ export type {
|
|
|
219
200
|
JavaScriptOptions,
|
|
220
201
|
JsdocOptions,
|
|
221
202
|
NextjsOptions,
|
|
203
|
+
OxlintOptions,
|
|
222
204
|
PackageJsonOptions,
|
|
223
|
-
PrettierOptions,
|
|
224
205
|
ReactOptions,
|
|
225
206
|
StorybookOptions,
|
|
226
207
|
StylisticOptions,
|
|
@@ -10,17 +10,6 @@ export interface OptionsOverrides {
|
|
|
10
10
|
overrides?: Partial<RulesConfig>
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
/**
|
|
14
|
-
* Stylistic options
|
|
15
|
-
*/
|
|
16
|
-
export interface OptionsStylistic {
|
|
17
|
-
/**
|
|
18
|
-
* Whether to enable stylistic rules
|
|
19
|
-
* @default true
|
|
20
|
-
*/
|
|
21
|
-
stylistic?: boolean
|
|
22
|
-
}
|
|
23
|
-
|
|
24
13
|
/**
|
|
25
14
|
* File matching options
|
|
26
15
|
*/
|
|
@@ -98,13 +87,13 @@ export interface DependOptions extends OptionsOverrides {
|
|
|
98
87
|
}
|
|
99
88
|
|
|
100
89
|
export interface IgnoresOptions {
|
|
101
|
-
/**
|
|
102
|
-
ignores?: string[] | false
|
|
103
|
-
/**
|
|
104
|
-
gitignore?:
|
|
90
|
+
/** Additional ignore patterns to merge with DEFAULT_IGNORES; pass false to disable all global ignores */
|
|
91
|
+
ignores?: string | string[] | false
|
|
92
|
+
/** Whether to parse .gitignore and merge into global ignores @default true */
|
|
93
|
+
gitignore?: boolean
|
|
105
94
|
}
|
|
106
95
|
|
|
107
|
-
export interface ImportsOptions extends OptionsOverrides
|
|
96
|
+
export interface ImportsOptions extends OptionsOverrides {
|
|
108
97
|
/**
|
|
109
98
|
* Whether to enable TypeScript support
|
|
110
99
|
* Automatically injected as true by composeConfig when the global typescript option is enabled
|
|
@@ -140,8 +129,6 @@ export interface PackageJsonOptions extends OptionsOverrides {
|
|
|
140
129
|
enforceForPrivate?: boolean
|
|
141
130
|
}
|
|
142
131
|
|
|
143
|
-
export type PrettierOptions = OptionsOverrides
|
|
144
|
-
|
|
145
132
|
export interface ReactOptions extends OptionsFiles, OptionsOverrides {
|
|
146
133
|
/**
|
|
147
134
|
* Whether to enable react-refresh plugin (for Vite projects).
|
|
@@ -163,3 +150,12 @@ export type UnicornOptions = OptionsFiles & OptionsOverrides
|
|
|
163
150
|
export type VitestOptions = OptionsFiles & OptionsOverrides & {
|
|
164
151
|
isInEditor?: boolean
|
|
165
152
|
}
|
|
153
|
+
|
|
154
|
+
export interface OxlintOptions {
|
|
155
|
+
/**
|
|
156
|
+
* Path to oxlint config file for dynamic rule generation.
|
|
157
|
+
* When provided, uses `buildFromOxlintConfigFile()` instead of the `flat/recommended` preset.
|
|
158
|
+
* @example './.oxlintrc.json'
|
|
159
|
+
*/
|
|
160
|
+
configFile?: string
|
|
161
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infra-x/create-eslint-config",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.2",
|
|
5
5
|
"description": "CLI to copy ESLint config source into a monorepo.",
|
|
6
6
|
"author": "infra-x",
|
|
7
7
|
"license": "MIT",
|
|
@@ -25,10 +25,11 @@
|
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^25.3.3",
|
|
28
|
+
"bumpp": "^10.4.1",
|
|
28
29
|
"eslint": "^10.0.2",
|
|
29
30
|
"tsdown": "^0.21.0",
|
|
30
31
|
"typescript": "^5.9.3",
|
|
31
|
-
"@infra-x/eslint-config": "0.1.
|
|
32
|
+
"@infra-x/eslint-config": "0.1.8",
|
|
32
33
|
"@infra-x/typescript-config": "0.1.6"
|
|
33
34
|
},
|
|
34
35
|
"exports": {
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
"scripts": {
|
|
39
40
|
"build": "tsdown",
|
|
40
41
|
"dev": "tsdown --watch",
|
|
41
|
-
"typecheck": "tsc --noEmit"
|
|
42
|
+
"typecheck": "tsc --noEmit",
|
|
43
|
+
"release": "bumpp"
|
|
42
44
|
}
|
|
43
45
|
}
|
package/README.md
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# @infra-x/create-eslint-config
|
|
2
|
-
|
|
3
|
-
CLI 工具,将完整的 ESLint 配置模板复制到 monorepo 的 `eslint-config/` 目录。
|
|
4
|
-
|
|
5
|
-
## 使用
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pnpm dlx @infra-x/create-eslint-config
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
在 monorepo 根目录执行,会将 `eslint-config/` 目录(含规则定义和 `composeConfig` 工厂函数)
|
|
12
|
-
复制到当前工作目录。如果目标路径存在冲突文件,会提示确认是否覆盖。
|
|
13
|
-
|
|
14
|
-
完整集成说明见[根目录 README](../../README.md)。
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ESLint ignore configuration with built-in default ignore patterns and .gitignore integration
|
|
3
|
-
*/
|
|
4
|
-
import { existsSync } from 'node:fs'
|
|
5
|
-
import path from 'node:path'
|
|
6
|
-
|
|
7
|
-
import { includeIgnoreFile } from '@eslint/compat'
|
|
8
|
-
|
|
9
|
-
import type { IgnoresOptions } from '../types'
|
|
10
|
-
import type { Linter } from 'eslint'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Default ignored files and directories
|
|
14
|
-
*/
|
|
15
|
-
export const DEFAULT_IGNORES: string[] = [
|
|
16
|
-
// Dependency directories
|
|
17
|
-
'**/node_modules/**',
|
|
18
|
-
'**/.pnp.*',
|
|
19
|
-
|
|
20
|
-
// Build artifacts
|
|
21
|
-
'**/dist/**',
|
|
22
|
-
'**/build/**',
|
|
23
|
-
'**/out/**',
|
|
24
|
-
'**/.next/**',
|
|
25
|
-
|
|
26
|
-
// Cache directories
|
|
27
|
-
'**/.cache/**',
|
|
28
|
-
'**/.turbo/**',
|
|
29
|
-
'**/.eslintcache',
|
|
30
|
-
|
|
31
|
-
// Version control
|
|
32
|
-
'**/.git/**',
|
|
33
|
-
'**/.svn/**',
|
|
34
|
-
'**/.hg/**',
|
|
35
|
-
'**/public/**',
|
|
36
|
-
|
|
37
|
-
// Type declaration files
|
|
38
|
-
'**/*.d.ts',
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
export function ignores(options: IgnoresOptions = {}): Linter.Config[] {
|
|
42
|
-
const { ignores: userIgnores, gitignore: gitignorePath } = options
|
|
43
|
-
const configs: Linter.Config[] = []
|
|
44
|
-
|
|
45
|
-
if (gitignorePath !== false) {
|
|
46
|
-
try {
|
|
47
|
-
const gitignoreFile
|
|
48
|
-
= typeof gitignorePath === 'string'
|
|
49
|
-
? path.resolve(gitignorePath)
|
|
50
|
-
: path.resolve(process.cwd(), '.gitignore')
|
|
51
|
-
|
|
52
|
-
if (existsSync(gitignoreFile)) {
|
|
53
|
-
configs.push(includeIgnoreFile(gitignoreFile))
|
|
54
|
-
}
|
|
55
|
-
} catch {
|
|
56
|
-
//
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const finalIgnores
|
|
61
|
-
= userIgnores === false
|
|
62
|
-
? []
|
|
63
|
-
: (userIgnores
|
|
64
|
-
? [...DEFAULT_IGNORES, ...userIgnores]
|
|
65
|
-
: DEFAULT_IGNORES)
|
|
66
|
-
|
|
67
|
-
if (finalIgnores.length > 0) {
|
|
68
|
-
configs.push({
|
|
69
|
-
name: 'defaults',
|
|
70
|
-
ignores: finalIgnores,
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return configs.map((config) => ({
|
|
75
|
-
...config,
|
|
76
|
-
name: `ignores/globals/${config.name}`,
|
|
77
|
-
}))
|
|
78
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prettier code formatting configuration using the official recommended ruleset
|
|
3
|
-
*/
|
|
4
|
-
import { defineConfig } from 'eslint/config'
|
|
5
|
-
import prettierConfig from 'eslint-plugin-prettier/recommended'
|
|
6
|
-
|
|
7
|
-
import { GLOB_SRC } from '../utils'
|
|
8
|
-
|
|
9
|
-
import type { PrettierOptions } from '../types'
|
|
10
|
-
import type { Linter } from 'eslint'
|
|
11
|
-
|
|
12
|
-
export function prettier(options: PrettierOptions = {}): Linter.Config[] {
|
|
13
|
-
const { overrides = {} } = options
|
|
14
|
-
|
|
15
|
-
const files = [GLOB_SRC]
|
|
16
|
-
|
|
17
|
-
return defineConfig([
|
|
18
|
-
{
|
|
19
|
-
name: 'prettier/rules',
|
|
20
|
-
files,
|
|
21
|
-
extends: [prettierConfig],
|
|
22
|
-
rules: overrides,
|
|
23
|
-
},
|
|
24
|
-
])
|
|
25
|
-
}
|