Skip to content

Commit

Permalink
feat(module): generate eslint.config.mjs automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 10, 2024
1 parent c75ebf1 commit 077271b
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 18 deletions.
1 change: 1 addition & 0 deletions packages/module/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"chokidar": "^3.6.0",
"eslint-flat-config-utils": "^0.2.1",
"eslint-typegen": "^0.2.1",
"find-up": "^7.0.0",
"get-port-please": "^3.1.2",
"mlly": "^1.6.1",
"pathe": "^1.1.2",
Expand Down
15 changes: 9 additions & 6 deletions packages/module/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { defineNuxtModule } from '@nuxt/kit'
import { setupConfigGen } from './modules/config'
import type { ModuleOptions } from './types'

export * from './types'
Expand All @@ -15,13 +14,17 @@ export default defineNuxtModule<ModuleOptions>({
},
async setup(options, nuxt) {
if (options.config) {
setupConfigGen(options, nuxt)
await import('./modules/config')
.then(({ setupConfigGen }) => setupConfigGen(options, nuxt))
}
if (options.checker) {
await import('./modules/checker')
.then(({ setupESLintChecker }) => {
setupESLintChecker(options, nuxt)
})
// TODO: maybe support build mode later on
if (nuxt.options.dev) {
await import('./modules/checker')
.then(({ setupESLintChecker }) => {
setupESLintChecker(options, nuxt)
})
}
}
},
})
5 changes: 0 additions & 5 deletions packages/module/src/modules/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ const flatConfigFiles = [
]

export async function setupESLintChecker(moduleOptions: ModuleOptions, nuxt: Nuxt) {
// TODO: maybe support build mode later on
if (!nuxt.options.dev) {
return
}

const options: CheckerOptions = {
cache: true,
include: [`${nuxt.options.srcDir}/**/*.{js,jsx,ts,tsx,vue}`],
Expand Down
56 changes: 54 additions & 2 deletions packages/module/src/modules/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { fileURLToPath, pathToFileURL } from 'node:url'
import { builtinModules } from 'node:module'
import { addTemplate, createResolver } from '@nuxt/kit'
import fs from 'node:fs/promises'
import { addTemplate, createResolver, logger } from '@nuxt/kit'
import { stringifyImports } from 'unimport'
import type { Import } from 'unimport'
import { resolvePath } from 'mlly'
Expand All @@ -15,6 +16,10 @@ import { createAddonGlobals } from '../config-addons/globals'
const r = createResolver(import.meta.url)

export async function setupConfigGen(options: ModuleOptions, nuxt: Nuxt) {
const {
autoInit = true,
} = typeof options.config !== 'boolean' ? options.config || {} : {}

const defaultAddons = [
createAddonGlobals(nuxt),
]
Expand All @@ -23,7 +28,7 @@ export async function setupConfigGen(options: ModuleOptions, nuxt: Nuxt) {
declarations.push('/// <reference path="./eslint-typegen.d.ts" />')
})

addTemplate({
const template = addTemplate({
filename: 'eslint.config.mjs',
write: true,
async getContents() {
Expand Down Expand Up @@ -53,9 +58,56 @@ export async function setupConfigGen(options: ModuleOptions, nuxt: Nuxt) {
},
})

if (autoInit) {
await initRootESLintConfig(nuxt, template.dst)
}

setupDevToolsIntegration(nuxt)
}

async function initRootESLintConfig(nuxt: Nuxt, generateConfigPath: string) {
const { findUp } = await import('find-up')

const hasFlatConfig = await findUp(
[
'eslint.config.js',
'eslint.config.mjs',
'eslint.config.cjs',
'eslint.config.ts',
'eslint.config.mts',
'eslint.config.cts',
],
{
cwd: nuxt.options.rootDir,
},
)

if (hasFlatConfig)
return

const targetPath = join(nuxt.options.rootDir, 'eslint.config.mjs')
let relativeDistPath = relative(nuxt.options.rootDir, generateConfigPath)
if (!relativeDistPath.startsWith('./') && !relativeDistPath.startsWith('../'))
relativeDistPath = './' + relativeDistPath

await fs.writeFile(
targetPath,
[
'// @ts-check',
`import withNuxt from '${relativeDistPath}'`,
'',
'export default withNuxt(',
' // Your custom configs here',
')',
'',
].join('\n'),
'utf-8',
)

logger.success(`ESLint config file created at ${targetPath}`)
logger.info(`If you have .eslintrc or .eslintignore files, you might want to migrate them to the new config file`)
}

async function generateESLintConfig(options: ModuleOptions, nuxt: Nuxt, addons: ESLintConfigGenAddon[]) {
const importLines: Import[] = []
const configItems: string[] = []
Expand Down
9 changes: 8 additions & 1 deletion packages/module/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ declare module '@nuxt/schema' {
}
}

export interface ConfigGenOptions extends NuxtESLintFeaturesOptions {}
export interface ConfigGenOptions extends NuxtESLintFeaturesOptions {
/**
* Create `eslint.config.mjs` file automatically if not exists
*
* @default true
*/
autoInit?: boolean
}

export interface CheckerOptions {
/**
Expand Down
4 changes: 0 additions & 4 deletions playground/eslint.config.js

This file was deleted.

5 changes: 5 additions & 0 deletions playground/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import withNuxt from './.nuxt/eslint.config.mjs'

export default withNuxt(
// Your custom configs here
)
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 077271b

Please sign in to comment.