Skip to content

Commit f5ccf3d

Browse files
committed
chore: wip
1 parent 7891379 commit f5ccf3d

File tree

13 files changed

+298
-59
lines changed

13 files changed

+298
-59
lines changed

storage/framework/stacks/core/eslint-config/README.md

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ Forked from [`@antfu/eslint-config`](https://github.com/antfu/eslint-config)
1212

1313
- Single quotes, no semi
1414
- Auto fix for formatting (aimed to be used standalone **without** Prettier)
15+
- Sorted imports, dangling commas
16+
- Reasonable defaults, best practices, only one line of config
1517
- Designed to work with TypeScript, JSX, Vue out-of-box
1618
- Lints also for json, yaml, toml, markdown
17-
- Sorted imports, dangling commas
18-
- Reasonable defaults, best practices, only one-line of config
1919
- Opinionated, but [very customizable](#customization)
2020
- [ESLint Flat config](https://eslint.org/docs/latest/use/configure/configuration-files-new), compose easily!
2121
- Using [ESLint Stylistic](https://github.com/eslint-stylistic/eslint-stylistic)
2222
- Respects `.gitignore` by default
23-
- Optional [formatters](#formatters) support for CSS, HTML, TOML, etc.
23+
- Optional [React](#react), [Svelte](#svelte), [UnoCSS](#unocss) support
24+
- Optional [formatters](#formatters) support for CSS, HTML, etc.
2425
- **Style principle**: Minimal for reading, stable for diff, consistent
2526

2627
> [!IMPORTANT]
@@ -54,6 +55,9 @@ const antfu = require('@antfu/eslint-config').default
5455
module.exports = antfu()
5556
```
5657

58+
> [!TIP]
59+
> ESLint only detects `eslint.config.js` as the flat config entry, meaning you need to put `type: module` in your `package.json` or you have to use CJS in `eslint.config.js`. If you want explicit extension like `.mjs` or `.cjs`, or even `eslint.config.ts`, you can install [`eslint-ts-patch`](https://github.com/antfu/eslint-ts-patch) to fix it.
60+
5761
Combined with legacy config:
5862

5963
```js
@@ -309,7 +313,10 @@ Certain rules would only be enabled in specific files, for example, `ts/*` rules
309313
import antfu from '@antfu/eslint-config'
310314

311315
export default antfu(
312-
{ vue: true, typescript: true },
316+
{
317+
vue: true,
318+
typescript: true
319+
},
313320
{
314321
// Remember to specify the file glob here, otherwise it might cause the vue plugin to handle non-vue files
315322
files: ['**/*.stx'],
@@ -326,23 +333,28 @@ export default antfu(
326333
)
327334
```
328335

329-
We also provided an `overrides` options to make it easier:
336+
We also provided a `overrides` options in each integration to make it easier:
330337

331338
```js
332339
// eslint.config.js
333340
import antfu from '@antfu/eslint-config'
334341

335342
export default antfu({
336-
overrides: {
337-
vue: {
343+
vue: {
344+
overrides: {
338345
'vue/operator-linebreak': ['error', 'before'],
339346
},
340-
typescript: {
347+
},
348+
typescript: {
349+
overrides: {
341350
'ts/consistent-type-definitions': ['error', 'interface'],
342351
},
343-
yaml: {},
344-
// ...
345-
}
352+
},
353+
yaml: {
354+
overrides: {
355+
// ...
356+
},
357+
},
346358
})
347359
```
348360

@@ -408,6 +420,25 @@ Running `npx eslint` should prompt you to install the required dependencies, oth
408420
npm i -D eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-react-refresh
409421
```
410422

423+
#### Svelte
424+
425+
To enable svelte support, you need to explicitly turn it on:
426+
427+
```js
428+
// eslint.config.js
429+
import antfu from '@antfu/eslint-config'
430+
431+
export default antfu({
432+
svelte: true,
433+
})
434+
```
435+
436+
Running `npx eslint` should prompt you to install the required dependencies, otherwise, you can install them manually:
437+
438+
```bash
439+
npm i -D eslint-plugin-svelte
440+
```
441+
411442
#### UnoCSS
412443

413444
To enable UnoCSS support, you need to explicitly turn it on:
@@ -540,15 +571,15 @@ Meanwhile, we do have dprint integrations for formatting other files such as `.m
540571

541572
You can opt-in to the [`formatters`](#formatters) feature to format your CSS. Note that it's only doing formatting, but not linting. If you want proper linting support, give [`stylelint`](https://stylelint.io/) a try.
542573

543-
### I prefer XXX
574+
### I prefer XXX...
544575

545576
Sure, you can configure and override rules locally in your project to fit your needs. If that still does not work for you, you can always fork this repo and maintain your own.
546577

547578
## Check Also
548579

549580
- [antfu/dotfiles](https://github.com/antfu/dotfiles) - My dotfiles
550581
- [antfu/vscode-settings](https://github.com/antfu/vscode-settings) - My VS Code settings
551-
- [antfu/ts-starter](https://github.com/antfu/ts-starter) - My starter template for TypeScript library
582+
- [antfu/starter-ts](https://github.com/antfu/starter-ts) - My starter template for TypeScript library
552583
- [antfu/vitesse](https://github.com/antfu/vitesse) - My starter template for Vue & Vite app
553584

554585
## License

storage/framework/stacks/core/eslint-config/src/configs/formatters.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import * as parserPlain from 'eslint-parser-plain'
21
import { GLOB_CSS, GLOB_LESS, GLOB_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS } from '../globs'
32
import type { VendoredPrettierOptions } from '../vender/prettier-types'
4-
import { ensurePackages, interopDefault } from '../utils'
3+
import { ensurePackages, interopDefault, parserPlain } from '../utils'
54
import type { FlatConfigItem, OptionsFormatters, StylisticConfig } from '../types'
65
import { StylisticConfigDefaults } from './stylistic'
76

@@ -151,6 +150,7 @@ export async function formatters(
151150
'error',
152151
formater === 'prettier'
153152
? {
153+
printWidth: 120,
154154
...prettierOptions,
155155
embeddedLanguageFormatting: 'off',
156156
parser: 'markdown',

storage/framework/stacks/core/eslint-config/src/configs/imports.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export async function imports(options: OptionsStylistic = {}): Promise<FlatConfi
1515
},
1616
rules: {
1717
'antfu/import-dedupe': 'error',
18+
'antfu/no-import-dist': 'error',
1819
'antfu/no-import-node-modules-by-path': 'error',
1920

2021
'import/first': 'error',

storage/framework/stacks/core/eslint-config/src/configs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export * from './formatters'
1111
export * from './react'
1212
export * from './sort'
1313
export * from './stylistic'
14+
export * from './svelte'
1415
export * from './test'
1516
export * from './typescript'
1617
export * from './unicorn'

storage/framework/stacks/core/eslint-config/src/configs/markdown.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import * as parserPlain from 'eslint-parser-plain'
21
import { mergeProcessors, processorPassThrough } from 'eslint-merge-processors'
32
import type { FlatConfigItem, OptionsComponentExts, OptionsFiles, OptionsOverrides } from '../types'
43
import { GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN } from '../globs'
5-
import { interopDefault } from '../utils'
4+
import { interopDefault, parserPlain } from '../utils'
65

76
export async function markdown(
87
options: OptionsFiles & OptionsComponentExts & OptionsOverrides = {},

storage/framework/stacks/core/eslint-config/src/configs/stylistic.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { interopDefault } from '../utils'
2-
import type { FlatConfigItem, StylisticConfig } from '../types'
2+
import type { FlatConfigItem, OptionsOverrides, StylisticConfig } from '../types'
33
import { pluginAntfu } from '../plugins'
44

55
export const StylisticConfigDefaults: StylisticConfig = {
@@ -9,10 +9,13 @@ export const StylisticConfigDefaults: StylisticConfig = {
99
semi: false,
1010
}
1111

12-
export async function stylistic(options: StylisticConfig = {}): Promise<FlatConfigItem[]> {
12+
export async function stylistic(
13+
options: StylisticConfig & OptionsOverrides = {},
14+
): Promise<FlatConfigItem[]> {
1315
const {
1416
indent,
1517
jsx,
18+
overrides = {},
1619
quotes,
1720
semi,
1821
} = {
@@ -46,6 +49,8 @@ export async function stylistic(options: StylisticConfig = {}): Promise<FlatConf
4649
'antfu/top-level-function': 'error',
4750

4851
'curly': ['error', 'multi-or-nest', 'consistent'],
52+
53+
...overrides,
4954
},
5055
},
5156
]
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { ensurePackages, interopDefault } from '../utils'
2+
import type { FlatConfigItem, OptionsFiles, OptionsHasTypeScript, OptionsOverrides, OptionsStylistic } from '../types'
3+
import { GLOB_SVELTE } from '../globs'
4+
5+
export async function svelte(
6+
options: OptionsHasTypeScript & OptionsOverrides & OptionsStylistic & OptionsFiles = {},
7+
): Promise<FlatConfigItem[]> {
8+
const {
9+
files = [GLOB_SVELTE],
10+
overrides = {},
11+
stylistic = true,
12+
} = options
13+
14+
const {
15+
indent = 2,
16+
quotes = 'single',
17+
} = typeof stylistic === 'boolean' ? {} : stylistic
18+
19+
await ensurePackages([
20+
'eslint-plugin-svelte',
21+
])
22+
23+
const [
24+
pluginSvelte,
25+
parserSvelte,
26+
] = await Promise.all([
27+
interopDefault(import('eslint-plugin-svelte')),
28+
interopDefault(import('svelte-eslint-parser')),
29+
] as const)
30+
31+
return [
32+
{
33+
name: 'antfu:svelte:setup',
34+
plugins: {
35+
svelte: pluginSvelte,
36+
},
37+
},
38+
{
39+
files,
40+
languageOptions: {
41+
parser: parserSvelte,
42+
parserOptions: {
43+
extraFileExtensions: ['.svelte'],
44+
parser: options.typescript
45+
? await interopDefault(import('@typescript-eslint/parser')) as any
46+
: null,
47+
},
48+
},
49+
name: 'antfu:svelte:rules',
50+
rules: {
51+
'import/no-mutable-exports': 'off',
52+
'no-undef': 'off', // incompatible with most recent (attribute-form) generic types RFC
53+
'no-unused-vars': ['error', {
54+
args: 'none',
55+
caughtErrors: 'none',
56+
ignoreRestSiblings: true,
57+
vars: 'all',
58+
varsIgnorePattern: '^\\$\\$Props$',
59+
}],
60+
61+
'svelte/comment-directive': 'error',
62+
'svelte/no-at-debug-tags': 'warn',
63+
'svelte/no-at-html-tags': 'error',
64+
'svelte/no-dupe-else-if-blocks': 'error',
65+
'svelte/no-dupe-style-properties': 'error',
66+
'svelte/no-dupe-use-directives': 'error',
67+
'svelte/no-dynamic-slot-name': 'error',
68+
'svelte/no-export-load-in-svelte-module-in-kit-pages': 'error',
69+
'svelte/no-inner-declarations': 'error',
70+
'svelte/no-not-function-handler': 'error',
71+
'svelte/no-object-in-text-mustaches': 'error',
72+
'svelte/no-reactive-functions': 'error',
73+
'svelte/no-reactive-literals': 'error',
74+
'svelte/no-shorthand-style-property-overrides': 'error',
75+
'svelte/no-unknown-style-directive-property': 'error',
76+
'svelte/no-unused-svelte-ignore': 'error',
77+
'svelte/no-useless-mustaches': 'error',
78+
'svelte/require-store-callbacks-use-set-param': 'error',
79+
'svelte/system': 'error',
80+
'svelte/valid-compile': 'error',
81+
'svelte/valid-each-key': 'error',
82+
83+
'unused-imports/no-unused-vars': [
84+
'error',
85+
{ args: 'after-used', argsIgnorePattern: '^_', vars: 'all', varsIgnorePattern: '^(_|\\$\\$Props$)' },
86+
],
87+
88+
...stylistic
89+
? {
90+
'style/no-trailing-spaces': 'off', // superseded by svelte/no-trailing-spaces
91+
'svelte/derived-has-same-inputs-outputs': 'error',
92+
'svelte/html-closing-bracket-spacing': 'error',
93+
'svelte/html-quotes': ['error', { prefer: quotes }],
94+
'svelte/indent': ['error', { alignAttributesVertically: true, indent }],
95+
'svelte/mustache-spacing': 'error',
96+
'svelte/no-spaces-around-equal-signs-in-attribute': 'error',
97+
'svelte/no-trailing-spaces': 'error',
98+
'svelte/spaced-html-comment': 'error',
99+
}
100+
: {},
101+
102+
...overrides,
103+
},
104+
},
105+
]
106+
}

storage/framework/stacks/core/eslint-config/src/configs/typescript.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import process from 'node:process'
2+
import { GLOB_SRC, GLOB_TS, GLOB_TSX } from '../globs'
23
import type { FlatConfigItem, OptionsComponentExts, OptionsFiles, OptionsOverrides, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes } from '../types'
3-
import { GLOB_SRC } from '../globs'
44
import { pluginAntfu } from '../plugins'
55
import { interopDefault, renameRules, toArray } from '../utils'
66

@@ -18,6 +18,8 @@ export async function typescript(
1818
...componentExts.map(ext => `**/*.${ext}`),
1919
]
2020

21+
const filesTypeAware = options.filesTypeAware ?? [GLOB_TS, GLOB_TSX]
22+
2123
const typeAwareRules: FlatConfigItem['rules'] = {
2224
'dot-notation': 'off',
2325
'no-implied-eval': 'off',
@@ -89,7 +91,6 @@ export async function typescript(
8991
'@typescript-eslint/',
9092
'ts/',
9193
),
92-
9394
'no-dupe-class-members': 'off',
9495
'no-loss-of-precision': 'off',
9596
'no-redeclare': 'off',
@@ -115,7 +116,13 @@ export async function typescript(
115116
'ts/prefer-ts-expect-error': 'error',
116117
'ts/triple-slash-reference': 'off',
117118
'ts/unified-signatures': 'off',
118-
119+
...overrides,
120+
},
121+
},
122+
{
123+
files: filesTypeAware,
124+
name: 'antfu:typescript:rules-type-aware',
125+
rules: {
119126
...tsconfigPath ? typeAwareRules : {},
120127
...overrides,
121128
},

0 commit comments

Comments
 (0)