Skip to content

Commit

Permalink
feat!: convert all configs to async, support on-demand import (#323)
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Nov 19, 2023
1 parent da2129f commit 234e92c
Show file tree
Hide file tree
Showing 23 changed files with 153 additions and 105 deletions.
31 changes: 16 additions & 15 deletions README.md
Expand Up @@ -223,6 +223,7 @@ We don't recommend using this style in general usages, as there are shared optio
```js
// eslint.config.js
import {
combine,
comments,
ignores,
imports,
Expand All @@ -240,21 +241,21 @@ import {
yaml,
} from '@antfu/eslint-config'

export default [
...ignores(),
...javascript(/* Options */),
...comments(),
...node(),
...jsdoc(),
...imports(),
...unicorn(),
...typescript(/* Options */),
...stylistic(),
...vue(),
...jsonc(),
...yaml(),
...markdown(),
]
export default combine(
ignores(),
javascript(/* Options */),
comments(),
node(),
jsdoc(),
imports(),
unicorn(),
typescript(/* Options */),
stylistic(),
vue(),
jsonc(),
yaml(),
markdown(),
)
```

</details>
Expand Down
4 changes: 2 additions & 2 deletions src/configs/comments.ts
@@ -1,7 +1,7 @@
import type { ConfigItem } from '../types'
import type { FlatConfigItem } from '../types'
import { pluginComments } from '../plugins'

export function comments(): ConfigItem[] {
export async function comments(): Promise<FlatConfigItem[]> {
return [
{
name: 'antfu:eslint-comments',
Expand Down
4 changes: 2 additions & 2 deletions src/configs/ignores.ts
@@ -1,7 +1,7 @@
import type { ConfigItem } from '../types'
import type { FlatConfigItem } from '../types'
import { GLOB_EXCLUDE } from '../globs'

export function ignores(): ConfigItem[] {
export async function ignores(): Promise<FlatConfigItem[]> {
return [
{
ignores: GLOB_EXCLUDE,
Expand Down
4 changes: 2 additions & 2 deletions src/configs/imports.ts
@@ -1,7 +1,7 @@
import type { ConfigItem, OptionsStylistic } from '../types'
import type { FlatConfigItem, OptionsStylistic } from '../types'
import { pluginAntfu, pluginImport } from '../plugins'

export function imports(options: OptionsStylistic = {}): ConfigItem[] {
export async function imports(options: OptionsStylistic = {}): Promise<FlatConfigItem[]> {
const {
stylistic = true,
} = options
Expand Down
7 changes: 4 additions & 3 deletions src/configs/javascript.ts
@@ -1,14 +1,15 @@
import globals from 'globals'
import type { ConfigItem, OptionsIsInEditor, OptionsOverrides } from '../types'
import type { FlatConfigItem, OptionsIsInEditor, OptionsOverrides } from '../types'
import { pluginAntfu, pluginUnusedImports } from '../plugins'
import { GLOB_SRC, GLOB_SRC_EXT } from '../globs'

export function javascript(options: OptionsIsInEditor & OptionsOverrides = {}): ConfigItem[] {
export async function javascript(
options: OptionsIsInEditor & OptionsOverrides = {},
): Promise<FlatConfigItem[]> {
const {
isInEditor = false,
overrides = {},
} = options

return [
{
languageOptions: {
Expand Down
9 changes: 5 additions & 4 deletions src/configs/jsdoc.ts
@@ -1,7 +1,7 @@
import type { ConfigItem, OptionsStylistic } from '../types'
import { pluginJsdoc } from '../plugins'
import { interopDefault } from 'src'
import type { FlatConfigItem, OptionsStylistic } from '../types'

export function jsdoc(options: OptionsStylistic = {}): ConfigItem[] {
export async function jsdoc(options: OptionsStylistic = {}): Promise<FlatConfigItem[]> {
const {
stylistic = true,
} = options
Expand All @@ -10,7 +10,8 @@ export function jsdoc(options: OptionsStylistic = {}): ConfigItem[] {
{
name: 'antfu:jsdoc',
plugins: {
jsdoc: pluginJsdoc,
// @ts-expect-error missing types
jsdoc: await interopDefault(import('eslint-plugin-jsdoc')),
},
rules: {
'jsdoc/check-access': 'warn',
Expand Down
14 changes: 11 additions & 3 deletions src/configs/jsonc.ts
@@ -1,8 +1,8 @@
import type { ConfigItem, OptionsOverrides, OptionsStylistic } from '../types'
import type { FlatConfigItem, OptionsOverrides, OptionsStylistic } from '../types'
import { GLOB_JSON, GLOB_JSON5, GLOB_JSONC } from '../globs'
import { parserJsonc, pluginJsonc } from '../plugins'
import { interopDefault } from '../utils'

export function jsonc(options: OptionsStylistic & OptionsOverrides = {}): ConfigItem[] {
export async function jsonc(options: OptionsStylistic & OptionsOverrides = {}): Promise<FlatConfigItem[]> {
const {
overrides = {},
stylistic = true,
Expand All @@ -12,6 +12,14 @@ export function jsonc(options: OptionsStylistic & OptionsOverrides = {}): Config
indent = 2,
} = typeof stylistic === 'boolean' ? {} : stylistic

const [
pluginJsonc,
parserJsonc,
] = await Promise.all([
interopDefault(import('eslint-plugin-jsonc')),
interopDefault(import('jsonc-eslint-parser')),
] as const)

return [
{
name: 'antfu:jsonc:setup',
Expand Down
9 changes: 5 additions & 4 deletions src/configs/markdown.ts
@@ -1,8 +1,8 @@
import type { ConfigItem, OptionsComponentExts, OptionsOverrides } from '../types'
import type { FlatConfigItem, OptionsComponentExts, OptionsOverrides } from '../types'
import { GLOB_MARKDOWN, GLOB_MARKDOWN_CODE } from '../globs'
import { pluginMarkdown } from '../plugins'
import { interopDefault } from '../utils'

export function markdown(options: OptionsComponentExts & OptionsOverrides = {}): ConfigItem[] {
export async function markdown(options: OptionsComponentExts & OptionsOverrides = {}): Promise<FlatConfigItem[]> {
const {
componentExts = [],
overrides = {},
Expand All @@ -12,7 +12,8 @@ export function markdown(options: OptionsComponentExts & OptionsOverrides = {}):
{
name: 'antfu:markdown:setup',
plugins: {
markdown: pluginMarkdown,
// @ts-expect-error missing types
markdown: await interopDefault(import('eslint-plugin-markdown')),
},
},
{
Expand Down
4 changes: 2 additions & 2 deletions src/configs/node.ts
@@ -1,7 +1,7 @@
import type { ConfigItem } from '../types'
import type { FlatConfigItem } from '../types'
import { pluginNode } from '../plugins'

export function node(): ConfigItem[] {
export async function node(): Promise<FlatConfigItem[]> {
return [
{
name: 'antfu:node',
Expand Down
4 changes: 2 additions & 2 deletions src/configs/perfectionist.ts
@@ -1,12 +1,12 @@
import type { ConfigItem } from '../types'
import type { FlatConfigItem } from '../types'
import { pluginPerfectionist } from '../plugins'

/**
* Optional perfectionist plugin for props and items sorting.
*
* @see https://github.com/azat-io/eslint-plugin-perfectionist
*/
export function perfectionist(): ConfigItem[] {
export async function perfectionist(): Promise<FlatConfigItem[]> {
return [
{
name: 'antfu:perfectionist',
Expand Down
6 changes: 3 additions & 3 deletions src/configs/sort.ts
@@ -1,11 +1,11 @@
import type { ConfigItem } from '../types'
import type { FlatConfigItem } from '../types'

/**
* Sort package.json
*
* Requires `jsonc` config
*/
export function sortPackageJson(): ConfigItem[] {
export async function sortPackageJson(): Promise<FlatConfigItem[]> {
return [
{
files: ['**/package.json'],
Expand Down Expand Up @@ -100,7 +100,7 @@ export function sortPackageJson(): ConfigItem[] {
* Requires `jsonc` config
*/

export function sortTsconfig(): ConfigItem[] {
export function sortTsconfig(): FlatConfigItem[] {
return [
{
files: ['**/tsconfig.json', '**/tsconfig.*.json'],
Expand Down
9 changes: 6 additions & 3 deletions src/configs/stylistic.ts
@@ -1,14 +1,17 @@
import type { ConfigItem, StylisticConfig } from '../types'
import { pluginAntfu, pluginStylistic } from '../plugins'
import { interopDefault } from 'src'
import type { FlatConfigItem, StylisticConfig } from '../types'
import { pluginAntfu } from '../plugins'

export function stylistic(options: StylisticConfig = {}): ConfigItem[] {
export async function stylistic(options: StylisticConfig = {}): Promise<FlatConfigItem[]> {
const {
indent = 2,
jsx = true,
quotes = 'single',
semi = false,
} = options

const pluginStylistic = await interopDefault(import('@stylistic/eslint-plugin'))

const config = pluginStylistic.configs.customize({
flat: true,
indent,
Expand Down
15 changes: 12 additions & 3 deletions src/configs/test.ts
@@ -1,13 +1,22 @@
import type { ConfigItem, OptionsIsInEditor, OptionsOverrides } from '../types'
import { pluginNoOnlyTests, pluginVitest } from '../plugins'
import { interopDefault } from 'src'
import type { FlatConfigItem, OptionsIsInEditor, OptionsOverrides } from '../types'
import { GLOB_TESTS } from '../globs'

export function test(options: OptionsIsInEditor & OptionsOverrides = {}): ConfigItem[] {
export async function test(options: OptionsIsInEditor & OptionsOverrides = {}): Promise<FlatConfigItem[]> {
const {
isInEditor = false,
overrides = {},
} = options

const [
pluginVitest,
pluginNoOnlyTests,
] = await Promise.all([
interopDefault(import('eslint-plugin-vitest')),
// @ts-expect-error missing types
interopDefault(import('eslint-plugin-no-only-tests')),
] as const)

return [
{
name: 'antfu:test:setup',
Expand Down
21 changes: 14 additions & 7 deletions src/configs/typescript.ts
@@ -1,19 +1,19 @@
import process from 'node:process'
import type { ConfigItem, OptionsComponentExts, OptionsOverrides, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes } from '../types'
import type { FlatConfigItem, OptionsComponentExts, OptionsOverrides, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes } from '../types'
import { GLOB_SRC } from '../globs'
import { parserTs, pluginAntfu, pluginImport, pluginTs } from '../plugins'
import { renameRules, toArray } from '../utils'
import { pluginAntfu } from '../plugins'
import { interopDefault, renameRules, toArray } from '../utils'

export function typescript(
export async function typescript(
options?: OptionsComponentExts & OptionsOverrides & OptionsTypeScriptWithTypes & OptionsTypeScriptParserOptions,
): ConfigItem[] {
): Promise<FlatConfigItem[]> {
const {
componentExts = [],
overrides = {},
parserOptions = {},
} = options ?? {}

const typeAwareRules: ConfigItem['rules'] = {
const typeAwareRules: FlatConfigItem['rules'] = {
'dot-notation': 'off',
'no-implied-eval': 'off',
'no-throw-literal': 'off',
Expand All @@ -39,13 +39,20 @@ export function typescript(
? toArray(options.tsconfigPath)
: undefined

const [
pluginTs,
parserTs,
] = await Promise.all([
interopDefault(import('@typescript-eslint/eslint-plugin')),
interopDefault(import('@typescript-eslint/parser')),
] as const)

return [
{
// Install the plugins without globs, so they can be configured separately.
name: 'antfu:typescript:setup',
plugins: {
antfu: pluginAntfu,
import: pluginImport,
ts: pluginTs as any,
},
},
Expand Down
4 changes: 2 additions & 2 deletions src/configs/unicorn.ts
@@ -1,7 +1,7 @@
import type { ConfigItem } from '../types'
import type { FlatConfigItem } from '../types'
import { pluginUnicorn } from '../plugins'

export function unicorn(): ConfigItem[] {
export async function unicorn(): Promise<FlatConfigItem[]> {
return [
{
name: 'antfu:unicorn',
Expand Down
21 changes: 16 additions & 5 deletions src/configs/vue.ts
@@ -1,10 +1,10 @@
import type { ConfigItem, OptionsHasTypeScript, OptionsOverrides, OptionsStylistic } from '../types'
import { interopDefault } from 'src'
import type { FlatConfigItem, OptionsHasTypeScript, OptionsOverrides, OptionsStylistic } from '../types'
import { GLOB_VUE } from '../globs'
import { parserTs, parserVue, pluginVue } from '../plugins'

export function vue(
export async function vue(
options: OptionsHasTypeScript & OptionsOverrides & OptionsStylistic = {},
): ConfigItem[] {
): Promise<FlatConfigItem[]> {
const {
overrides = {},
stylistic = true,
Expand All @@ -14,6 +14,15 @@ export function vue(
indent = 2,
} = typeof stylistic === 'boolean' ? {} : stylistic

const [
pluginVue,
parserVue,
] = await Promise.all([
// @ts-expect-error missing types
interopDefault(import('eslint-plugin-vue')),
interopDefault(import('vue-eslint-parser')),
] as const)

return [
{
name: 'antfu:vue:setup',
Expand All @@ -30,7 +39,9 @@ export function vue(
jsx: true,
},
extraFileExtensions: ['.vue'],
parser: options.typescript ? parserTs as any : null,
parser: options.typescript
? await interopDefault(import('@typescript-eslint/parser')) as any
: null,
sourceType: 'module',
},
},
Expand Down
18 changes: 13 additions & 5 deletions src/configs/yaml.ts
@@ -1,10 +1,10 @@
import type { ConfigItem, OptionsOverrides, OptionsStylistic } from '../types'
import type { FlatConfigItem, OptionsOverrides, OptionsStylistic } from '../types'
import { GLOB_YAML } from '../globs'
import { parserYaml, pluginYaml } from '../plugins'
import { interopDefault } from '../utils'

export function yaml(
export async function yaml(
options: OptionsOverrides & OptionsStylistic = {},
): ConfigItem[] {
): Promise<FlatConfigItem[]> {
const {
overrides = {},
stylistic = true,
Expand All @@ -15,11 +15,19 @@ export function yaml(
quotes = 'single',
} = typeof stylistic === 'boolean' ? {} : stylistic

const [
pluginYaml,
parserYaml,
] = await Promise.all([
interopDefault(import('eslint-plugin-yml')),
interopDefault(import('yaml-eslint-parser')),
] as const)

return [
{
name: 'antfu:yaml:setup',
plugins: {
yaml: pluginYaml as any,
yaml: pluginYaml,
},
},
{
Expand Down

0 comments on commit 234e92c

Please sign in to comment.