Generate ESLint config from current Nuxt settings
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Hook system and addon support for extending ESLint configuration. The module provides a flexible architecture for customizing and extending the generated ESLint configuration through hooks and addons.
Interface for creating addons that extend the generated ESLint configuration.
/**
* Addon configuration for extending generated ESLint config
*/
interface ESLintConfigGenAddon {
/** Unique identifier for the addon */
name: string;
/** Function that returns configuration to be merged */
getConfigs: () => Awaitable<ESLintConfigGenAddonResult | undefined>;
}
/**
* Result object returned by config generation addons
*/
interface ESLintConfigGenAddonResult {
/**
* Import statements to add to the generated ESLint config
* These will be resolved and added to the config file imports
*/
imports?: Import[];
/**
* Flat config items, should be stringified lines
* These are JavaScript code strings that will be added to the config
*/
configs?: string[];
}
/**
* Import statement definition for config generation
*/
interface Import {
/** Module name to import from */
from: string;
/** Named import or default import name */
name: string;
/** Alias for the import (optional) */
as?: string;
}
/**
* Utility type for sync or async values
*/
type Awaitable<T> = T | Promise<T>;The module extends Nuxt's hook system with ESLint-specific hooks.
/**
* ESLint-specific hooks added to Nuxt's hook system
*/
declare module '@nuxt/schema' {
interface NuxtHooks {
/**
* Called before generating ESLint config, can be used to register custom ESLint config addons
* @param addons - Array of ESLint config generation addons
*/
'eslint:config:addons': (addons: ESLintConfigGenAddon[]) => void;
}
}Usage Examples:
// In a Nuxt plugin or module
export default defineNuxtPlugin(() => {
const nuxt = useNuxt()
nuxt.hook('eslint:config:addons', (addons) => {
addons.push({
name: 'my-custom-addon',
async getConfigs() {
return {
imports: [
{ from: 'my-eslint-plugin', name: 'default', as: 'myPlugin' }
],
configs: [
`{
name: 'my-custom-config',
plugins: { myPlugin },
rules: {
'my-plugin/my-rule': 'error'
}
}`
]
}
}
})
})
})The module includes several built-in addons that demonstrate the addon system.
/**
* Built-in addon for integrating Nuxt import globals into ESLint config
*/
interface ImportGlobalsAddon extends ESLintConfigGenAddon {
name: 'nuxt:eslint:import-globals';
getConfigs(): Promise<ESLintConfigGenAddonResult>;
}
/**
* Creates the import globals addon for a Nuxt instance
* @param nuxt - Nuxt instance to extract imports from
* @returns Configured addon for import globals
*/
function createAddonGlobals(nuxt: Nuxt): ImportGlobalsAddon;Creating custom addons for extending ESLint configuration.
/**
* Example custom addon for TypeScript-specific rules
*/
const typescriptAddon: ESLintConfigGenAddon = {
name: 'typescript-strict',
async getConfigs() {
return {
imports: [
{ from: '@typescript-eslint/eslint-plugin', name: 'default', as: 'tsPlugin' }
],
configs: [
`{
name: 'typescript-strict',
files: ['**/*.ts', '**/*.tsx'],
plugins: { '@typescript-eslint': tsPlugin },
rules: {
'@typescript-eslint/no-any': 'error',
'@typescript-eslint/strict-boolean-expressions': 'error'
}
}`
]
}
}
}Usage Examples:
// Register addon through hook in nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/eslint'],
hooks: {
'eslint:config:addons': (addons) => {
// Add custom Vue 3 composition API rules
addons.push({
name: 'vue3-composition',
getConfigs() {
return {
imports: [
{ from: 'eslint-plugin-vue', name: 'default', as: 'vuePlugin' }
],
configs: [
`{
name: 'vue3-composition-rules',
files: ['**/*.vue'],
plugins: { vue: vuePlugin },
rules: {
'vue/prefer-composition-api': 'error',
'vue/no-deprecated-v-on-native-modifier': 'error'
}
}`
]
}
}
})
// Add custom import sorting rules
addons.push({
name: 'import-sorting',
getConfigs() {
return {
imports: [
{ from: 'eslint-plugin-import', name: 'default', as: 'importPlugin' }
],
configs: [
`{
name: 'import-sorting',
plugins: { import: importPlugin },
rules: {
'import/order': ['error', {
'groups': ['builtin', 'external', 'internal', 'parent', 'sibling'],
'newlines-between': 'always'
}]
}
}`
]
}
}
})
}
}
})The addon system follows a specific lifecycle during config generation:
eslint:config:addons hook is called with addon arraygetConfigs() method is executed/**
* Conditional addon that applies different rules based on environment
*/
const environmentAddon: ESLintConfigGenAddon = {
name: 'environment-specific',
async getConfigs() {
const isDev = process.env.NODE_ENV === 'development'
return {
configs: [
`{
name: 'environment-rules',
rules: {
'no-console': ${isDev ? '"warn"' : '"error"'},
'no-debugger': ${isDev ? '"warn"' : '"error"'}
}
}`
]
}
}
}
/**
* Dynamic addon that reads configuration from external file
*/
const dynamicAddon: ESLintConfigGenAddon = {
name: 'dynamic-config',
async getConfigs() {
const configPath = resolve('./eslint.custom.json')
const customConfig = await readFile(configPath, 'utf-8').catch(() => null)
if (!customConfig) return undefined
return {
configs: [
`// Custom configuration from ${configPath}`,
customConfig
]
}
}
}The extensibility system integrates with several parts of the module:
When developing custom addons:
getConfigs() methodsInstall with Tessl CLI
npx tessl i tessl/npm-nuxt--eslint