Skip to content

Commit

Permalink
feat(module): generate configuration for globals (#336)
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Mar 19, 2024
1 parent 16e85a8 commit ee98b29
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 14 deletions.
24 changes: 24 additions & 0 deletions packages/module/src/config-addons/globals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Nuxt } from '@nuxt/schema'
import type { Unimport } from 'unimport'
import type { ESLintConfigGenAddon } from '../types'
import type { FlatConfig } from '@nuxt/eslint-config/flat'

export function createAddonGlobals(nuxt: Nuxt): ESLintConfigGenAddon {
let unimport: Unimport

nuxt.hook('imports:context', (context) => {
unimport = context
})

return async () => ({
configs: [
'// Set globals from imports registry\n'
+ JSON.stringify(<FlatConfig>{
name: 'nuxt:import-globals',
languageOptions: {
globals: Object.fromEntries((await unimport.getImports()).map(i => [i.as || i.name, 'readonly'])),
},
}),
],
})
}
33 changes: 23 additions & 10 deletions packages/module/src/modules/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ import type { Import } from 'unimport'
import type { Nuxt } from '@nuxt/schema'
import { relative, resolve } from 'pathe'
import { getPort } from 'get-port-please'
import type { ESLintPluginAddon } from '../types'
import type { ESLintConfigGenAddon } from '../types'
import type { NuxtESLintConfigOptions } from '@nuxt/eslint-config/flat'
import { ConfigGenOptions, ModuleOptions } from '../module'
import { createAddonGlobals } from '../config-addons/globals'

export function setupConfigGen(options: ModuleOptions, nuxt: Nuxt) {
const addons: ESLintPluginAddon[] = []
export async function setupConfigGen(options: ModuleOptions, nuxt: Nuxt) {
const addons: ESLintConfigGenAddon[] = [
createAddonGlobals(nuxt),
]

// TODO: hook to add more addons
// nuxt.hook('app:resolve', async () => {
// await nuxt.callHook('eslint:config:addons', addons)
// })

addTemplate({
filename: 'eslint.config.mjs',
write: true,
Expand All @@ -23,9 +30,9 @@ export function setupConfigGen(options: ModuleOptions, nuxt: Nuxt) {
setupDevToolsIntegration(nuxt)
}

function generateESLintConfig(options: ModuleOptions, nuxt: Nuxt, addons: ESLintPluginAddon[]) {
async function generateESLintConfig(options: ModuleOptions, nuxt: Nuxt, addons: ESLintConfigGenAddon[]) {
const importLines: Import[] = []
const configLines: string[] = []
const configItems: string[] = []

const config: ConfigGenOptions = {
standalone: true,
Expand All @@ -46,22 +53,27 @@ function generateESLintConfig(options: ModuleOptions, nuxt: Nuxt, addons: ESLint
dirs: getDirs(nuxt),
}

configLines.push(`...createConfigForNuxt(\n${JSON.stringify(basicOptions, null, 2)}\n),`)
configItems.push(`// Nuxt Configs\n...createConfigForNuxt(${JSON.stringify(basicOptions, null, 2)})`)

for (const mod of addons) {
importLines.push(...mod.imports)
configLines.push(...mod.configs)
for (const addon of addons) {
const resolved = await addon()
if (resolved?.imports)
importLines.push(...resolved.imports)
if (resolved?.configs)
configItems.push(...resolved.configs)
}

return [
'// ESLint config generated by Nuxt',
stringifyImports(importLines, false),
'',
`export default [`,
...configLines,
configItems.join(',\n\n'),
`]`,
'',
].join('\n')
}

function setupDevToolsIntegration(nuxt: Nuxt) {
let viewerProcess: ReturnType<typeof import('@nuxt/devtools-kit')['startSubprocess']> | undefined
let viewerPort: number | undefined
Expand Down Expand Up @@ -124,6 +136,7 @@ function setupDevToolsIntegration(nuxt: Nuxt) {
})
})
}

function getDirs(nuxt: Nuxt): NuxtESLintConfigOptions['dirs'] {
const dirs: Required<NuxtESLintConfigOptions['dirs']> = {
pages: [],
Expand Down
19 changes: 15 additions & 4 deletions packages/module/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Import } from 'unimport'
import type { ESLintPluginOptions as ViteCheckerOptions } from 'vite-plugin-eslint2'
import type { Options as WebpackCheckerOptions } from 'eslint-webpack-plugin'
import { NuxtESLintFeaturesOptions } from '@nuxt/eslint-config/flat'
import { FlatConfig, NuxtESLintFeaturesOptions } from '@nuxt/eslint-config/flat'

Check warning on line 4 in packages/module/src/types.ts

View workflow job for this annotation

GitHub Actions / ci

'FlatConfig' is defined but never used
import { Nuxt } from '@nuxt/schema'

Check warning on line 5 in packages/module/src/types.ts

View workflow job for this annotation

GitHub Actions / ci

'Nuxt' is defined but never used

export interface ConfigGenOptions extends NuxtESLintFeaturesOptions {}

Expand Down Expand Up @@ -91,7 +92,17 @@ export interface ModuleOptions {
checker?: CheckerOptions | boolean
}

export interface ESLintPluginAddon {
imports: Import[]
configs: string[]
export interface ESLintConfigGenAddonResult {
/**
* Imports statements to add to the generated ESLint config
*/
imports?: Import[]
/**
* Flat config items, should be stringified
*/
configs?: string[]
}

export type Awaitable<T> = T | Promise<T>

export type ESLintConfigGenAddon = () => Awaitable<ESLintConfigGenAddonResult | void>

0 comments on commit ee98b29

Please sign in to comment.