Skip to content

Commit

Permalink
feat!: rename plugin prefixes for consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Sep 21, 2023
1 parent 7070dc9 commit f31a824
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 139 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Expand Up @@ -15,6 +15,7 @@
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "@stylistic/*", "severity": "off" },
{ "rule": "style*", "severity": "off" },
{ "rule": "*-indent", "severity": "off" },
{ "rule": "*-spacing", "severity": "off" },
{ "rule": "*-spaces", "severity": "off" },
Expand Down
22 changes: 21 additions & 1 deletion README.md
Expand Up @@ -100,7 +100,7 @@ Add the following settings to your `settings.json`:
}
```

## Flat Config
## Customization

Since v1.0, we migrated to [ESLint Flat config](https://eslint.org/docs/latest/use/configure/configuration-files-new), provides a much better organization and composition.

Expand Down Expand Up @@ -197,6 +197,26 @@ Check out the [configs](https://github.com/antfu/eslint-config/blob/main/package

> Thanks to [sxzz/eslint-config](https://github.com/sxzz/eslint-config) for the inspiration and reference.
## Plugins Renaming

Since flat config support explicit provides the plugin names, we renamed some plugins to make them more consistent and hide the implementation details.

| Original Prefix | New Prefix | Source Plugin |
| --------------- | ---------- | ------------- |
| `i/*` | `import/*` | [eslint-plugin-i](https://github.com/un-es/eslint-plugin-i) |
| `n/*` | `node` | [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n)
| `@typescript-eslint/*` | `ts/*` | [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint) |
| `@stylistic/js` | `style/*` | [@stylistic/eslint-plugin-js](https://github.com/eslint-stylistic/eslint-stylistic) |
| `@stylistic/ts` | `style-ts/` | [@stylistic/eslint-plugin-ts](https://github.com/eslint-stylistic/eslint-stylistic) |

When you want to overrides rules, or disable them inline, you need to update to the new prefix:

```diff
-// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
+// eslint-disable-next-line ts/consistent-type-definitions
type foo = { bar: 2 }
```

### Type Aware Rules

You can optionally enable the [type aware rules](https://typescript-eslint.io/linting/typed-linting/) by passing the options object to the `typescript` config:
Expand Down
26 changes: 15 additions & 11 deletions packages/eslint-config/src/configs/markdown.ts
@@ -1,6 +1,6 @@
import type { FlatESLintConfigItem } from 'eslint-define-config'
import { GLOB_MARKDOWN, GLOB_MARKDOWN_CODE } from '../globs'
import { pluginMarkdown } from '../plugins'
import { pluginMarkdown, pluginTs } from '../plugins'
import { OFF } from '../flags'
import type { OptionsComponentExts } from '../types'

Expand Down Expand Up @@ -29,30 +29,34 @@ export function markdown(options: OptionsComponentExts = {}): FlatESLintConfigIt
},
},
},
plugins: {
ts: pluginTs as any,
},
rules: {
...pluginMarkdown.configs.recommended.overrides[1].rules,
'@typescript-eslint/comma-dangle': OFF,
'@typescript-eslint/consistent-type-imports': OFF,
'@typescript-eslint/no-namespace': OFF,
'@typescript-eslint/no-redeclare': OFF,
'@typescript-eslint/no-require-imports': OFF,
'@typescript-eslint/no-unused-vars': OFF,
'@typescript-eslint/no-use-before-define': OFF,
'@typescript-eslint/no-var-requires': OFF,

'antfu/no-cjs-exports': OFF,
'antfu/no-ts-export-equal': OFF,

'import/no-unresolved': OFF,

'n/prefer-global/process': OFF,

'no-alert': OFF,
'no-console': OFF,
'no-restricted-imports': OFF,
'no-undef': OFF,
'no-unused-expressions': OFF,
'no-unused-vars': OFF,

'node/prefer-global/process': OFF,

'ts/comma-dangle': OFF,
'ts/consistent-type-imports': OFF,
'ts/no-namespace': OFF,
'ts/no-redeclare': OFF,
'ts/no-require-imports': OFF,
'ts/no-unused-vars': OFF,
'ts/no-use-before-define': OFF,
'ts/no-var-requires': OFF,

'unused-imports/no-unused-imports': OFF,
'unused-imports/no-unused-vars': OFF,
Expand Down
19 changes: 9 additions & 10 deletions packages/eslint-config/src/configs/node.ts
Expand Up @@ -4,18 +4,17 @@ import { pluginNode } from '../plugins'
export const node: FlatESLintConfigItem[] = [
{
plugins: {
n: pluginNode,
node: pluginNode,
},
rules: {
// Node
'n/handle-callback-err': ['error', '^(err|error)$'],
'n/no-deprecated-api': 'error',
'n/no-exports-assign': 'error',
'n/no-new-require': 'error',
'n/no-path-concat': 'error',
'n/prefer-global/buffer': ['error', 'never'],
'n/prefer-global/process': ['error', 'never'],
'n/process-exit-as-throw': 'error',
'node/handle-callback-err': ['error', '^(err|error)$'],
'node/no-deprecated-api': 'error',
'node/no-exports-assign': 'error',
'node/no-new-require': 'error',
'node/no-path-concat': 'error',
'node/prefer-global/buffer': ['error', 'never'],
'node/prefer-global/process': ['error', 'never'],
'node/process-exit-as-throw': 'error',
},
},
]
135 changes: 77 additions & 58 deletions packages/eslint-config/src/configs/stylistic.ts
@@ -1,25 +1,34 @@
import type { FlatESLintConfigItem } from 'eslint-define-config'
import { rules } from '@eslint-stylistic/metadata'
import { pluginStylisticJs, pluginStylisticTs } from '../plugins'
import { packages } from '@eslint-stylistic/metadata'
import { pluginStylisticJs, pluginStylisticTs, pluginTs } from '../plugins'
import { OFF } from '../flags'

const tsPackage = packages.find(i => i.shortId === 'ts')!
const jsPackage = packages.find(i => i.shortId === 'js')!

export const javascriptStylistic: FlatESLintConfigItem[] = [
{
plugins: {
'@stylistic/js': pluginStylisticJs,
style: pluginStylisticJs,
},
rules: {
'@stylistic/js/array-bracket-spacing': ['error', 'never'],
'@stylistic/js/arrow-spacing': ['error', { after: true, before: true }],
'@stylistic/js/block-spacing': ['error', 'always'],
'@stylistic/js/brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
'@stylistic/js/comma-spacing': ['error', { after: true, before: false }],
'@stylistic/js/comma-style': ['error', 'last'],
'@stylistic/js/computed-property-spacing': ['error', 'never', { enforceForClassMembers: true }],
'@stylistic/js/dot-location': ['error', 'property'],
'@stylistic/js/func-call-spacing': OFF,
'@stylistic/js/generator-star-spacing': OFF,
'@stylistic/js/indent': ['error', 2, {
'antfu/if-newline': 'error',
'comma-dangle': ['error', 'always-multiline'],
'curly': ['error', 'multi-or-nest', 'consistent'],
'quotes': ['error', 'single'],
'semi': ['error', 'never'],

'style/array-bracket-spacing': ['error', 'never'],
'style/arrow-spacing': ['error', { after: true, before: true }],
'style/block-spacing': ['error', 'always'],
'style/brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
'style/comma-spacing': ['error', { after: true, before: false }],
'style/comma-style': ['error', 'last'],
'style/computed-property-spacing': ['error', 'never', { enforceForClassMembers: true }],
'style/dot-location': ['error', 'property'],
'style/func-call-spacing': OFF,
'style/generator-star-spacing': OFF,
'style/indent': ['error', 2, {
ArrayExpression: 1,
CallExpression: { arguments: 1 },
FunctionDeclaration: { body: 1, parameters: 1 },
Expand Down Expand Up @@ -57,29 +66,29 @@ export const javascriptStylistic: FlatESLintConfigItem[] = [
offsetTernaryExpressions: true,
outerIIFEBody: 1,
}],
'@stylistic/js/key-spacing': ['error', { afterColon: true, beforeColon: false }],
'@stylistic/js/keyword-spacing': ['error', { after: true, before: true }],
'@stylistic/js/lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
'@stylistic/js/multiline-ternary': ['error', 'always-multiline'],
'@stylistic/js/no-mixed-spaces-and-tabs': 'error',
'@stylistic/js/no-multi-spaces': 'error',
'@stylistic/js/no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }],
'@stylistic/js/no-tabs': 'error',
'@stylistic/js/no-trailing-spaces': 'error',
'@stylistic/js/no-whitespace-before-property': 'error',
'@stylistic/js/object-curly-newline': ['error', { consistent: true, multiline: true }],
'@stylistic/js/object-curly-spacing': ['error', 'always'],
'@stylistic/js/object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }],
'@stylistic/js/operator-linebreak': ['error', 'before'],
'@stylistic/js/padded-blocks': ['error', { blocks: 'never', classes: 'never', switches: 'never' }],
'@stylistic/js/rest-spread-spacing': ['error', 'never'],
'@stylistic/js/semi-spacing': ['error', { after: true, before: false }],
'@stylistic/js/space-before-blocks': ['error', 'always'],
'@stylistic/js/space-before-function-paren': ['error', { anonymous: 'always', asyncArrow: 'always', named: 'never' }],
'@stylistic/js/space-in-parens': ['error', 'never'],
'@stylistic/js/space-infix-ops': 'error',
'@stylistic/js/space-unary-ops': ['error', { nonwords: false, words: true }],
'@stylistic/js/spaced-comment': ['error', 'always', {
'style/key-spacing': ['error', { afterColon: true, beforeColon: false }],
'style/keyword-spacing': ['error', { after: true, before: true }],
'style/lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
'style/multiline-ternary': ['error', 'always-multiline'],
'style/no-mixed-spaces-and-tabs': 'error',
'style/no-multi-spaces': 'error',
'style/no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }],
'style/no-tabs': 'error',
'style/no-trailing-spaces': 'error',
'style/no-whitespace-before-property': 'error',
'style/object-curly-newline': ['error', { consistent: true, multiline: true }],
'style/object-curly-spacing': ['error', 'always'],
'style/object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }],
'style/operator-linebreak': ['error', 'before'],
'style/padded-blocks': ['error', { blocks: 'never', classes: 'never', switches: 'never' }],
'style/rest-spread-spacing': ['error', 'never'],
'style/semi-spacing': ['error', { after: true, before: false }],
'style/space-before-blocks': ['error', 'always'],
'style/space-before-function-paren': ['error', { anonymous: 'always', asyncArrow: 'always', named: 'never' }],
'style/space-in-parens': ['error', 'never'],
'style/space-infix-ops': 'error',
'style/space-unary-ops': ['error', { nonwords: false, words: true }],
'style/spaced-comment': ['error', 'always', {
block: {
balanced: true,
exceptions: ['*'],
Expand All @@ -90,51 +99,61 @@ export const javascriptStylistic: FlatESLintConfigItem[] = [
markers: ['/'],
},
}],
'@stylistic/js/template-curly-spacing': 'error',
'@stylistic/js/template-tag-spacing': ['error', 'never'],
'@stylistic/js/yield-star-spacing': ['error', 'both'],

'antfu/if-newline': 'error',
'comma-dangle': ['error', 'always-multiline'],
'curly': ['error', 'multi-or-nest', 'consistent'],
'quotes': ['error', 'single'],
'semi': ['error', 'never'],
'style/template-curly-spacing': 'error',
'style/template-tag-spacing': ['error', 'never'],
'style/yield-star-spacing': ['error', 'both'],
},
},
]

export const typescriptStylistic: FlatESLintConfigItem[] = [
{
plugins: {
'@stylistic/js': pluginStylisticJs,
'@stylistic/ts': pluginStylisticTs,
'style-ts': pluginStylisticTs,
'ts': pluginTs as any,
},
rules: {
...stylisticJsToTS(rules),
'@stylistic/ts/member-delimiter-style': ['error', { multiline: { delimiter: 'none' } }],
'@stylistic/ts/type-annotation-spacing': ['error', {}],
...stylisticJsToTS(javascriptStylistic[0].rules!),

'comma-dangle': OFF,
'quotes': OFF,
'semi': OFF,

'style-ts/member-delimiter-style': ['error', { multiline: { delimiter: 'none' } }],
'style-ts/type-annotation-spacing': ['error', {}],

'ts/comma-dangle': ['error', 'always-multiline'],
'ts/quotes': ['error', 'single'],
'ts/semi': ['error', 'never'],
},
},
]

// TODO: move to ESLint Stylistic
function stylisticJsToTS(input: Record<string, any>) {
return {
// turn off all stylistic rules from @stylistic/js
// turn off all stylistic rules from style
...Object.fromEntries(
Object.entries(input)
.map(([key]) => rules.find(i => i.name === key) ? [key, OFF] : null!)
.map(([key]) => {
if (!key.startsWith('style/'))
return null!
const basename = key.replace('style/', '')
if (jsPackage.rules.find(i => i.name === basename))
return [key, OFF]
return null!
})
.filter(Boolean),
),
// rename all stylistic rules from @stylistic/js to @stylistic/ts
// rename all stylistic rules from style to style/ts
...Object.fromEntries(
Object.entries(input)
.map(([key, value]) => {
const newKey = key.replace('@stylistic/js', '@stylistic/ts')
if (newKey === key)
if (!key.startsWith('style/'))
return null!
return rules.find(i => i.name === newKey)
? [key.replace('@stylistic/js', '@stylistic/ts'), value]
const basename = key.replace('style/', '')
return tsPackage.rules.find(i => i.name === basename)
? [`style-ts/${basename}`, value]
: null!
})
.filter(Boolean),
Expand Down

0 comments on commit f31a824

Please sign in to comment.