0
# Extensibility
1
2
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.
3
4
## Capabilities
5
6
### ESLint Config Generation Addon
7
8
Interface for creating addons that extend the generated ESLint configuration.
9
10
```typescript { .api }
11
/**
12
* Addon configuration for extending generated ESLint config
13
*/
14
interface ESLintConfigGenAddon {
15
/** Unique identifier for the addon */
16
name: string;
17
/** Function that returns configuration to be merged */
18
getConfigs: () => Awaitable<ESLintConfigGenAddonResult | undefined>;
19
}
20
21
/**
22
* Result object returned by config generation addons
23
*/
24
interface ESLintConfigGenAddonResult {
25
/**
26
* Import statements to add to the generated ESLint config
27
* These will be resolved and added to the config file imports
28
*/
29
imports?: Import[];
30
31
/**
32
* Flat config items, should be stringified lines
33
* These are JavaScript code strings that will be added to the config
34
*/
35
configs?: string[];
36
}
37
38
/**
39
* Import statement definition for config generation
40
*/
41
interface Import {
42
/** Module name to import from */
43
from: string;
44
/** Named import or default import name */
45
name: string;
46
/** Alias for the import (optional) */
47
as?: string;
48
}
49
50
/**
51
* Utility type for sync or async values
52
*/
53
type Awaitable<T> = T | Promise<T>;
54
```
55
56
### Nuxt Hooks Integration
57
58
The module extends Nuxt's hook system with ESLint-specific hooks.
59
60
```typescript { .api }
61
/**
62
* ESLint-specific hooks added to Nuxt's hook system
63
*/
64
declare module '@nuxt/schema' {
65
interface NuxtHooks {
66
/**
67
* Called before generating ESLint config, can be used to register custom ESLint config addons
68
* @param addons - Array of ESLint config generation addons
69
*/
70
'eslint:config:addons': (addons: ESLintConfigGenAddon[]) => void;
71
}
72
}
73
```
74
75
**Usage Examples:**
76
77
```typescript
78
// In a Nuxt plugin or module
79
export default defineNuxtPlugin(() => {
80
const nuxt = useNuxt()
81
82
nuxt.hook('eslint:config:addons', (addons) => {
83
addons.push({
84
name: 'my-custom-addon',
85
async getConfigs() {
86
return {
87
imports: [
88
{ from: 'my-eslint-plugin', name: 'default', as: 'myPlugin' }
89
],
90
configs: [
91
`{
92
name: 'my-custom-config',
93
plugins: { myPlugin },
94
rules: {
95
'my-plugin/my-rule': 'error'
96
}
97
}`
98
]
99
}
100
}
101
})
102
})
103
})
104
```
105
106
### Built-in Addons
107
108
The module includes several built-in addons that demonstrate the addon system.
109
110
```typescript { .api }
111
/**
112
* Built-in addon for integrating Nuxt import globals into ESLint config
113
*/
114
interface ImportGlobalsAddon extends ESLintConfigGenAddon {
115
name: 'nuxt:eslint:import-globals';
116
getConfigs(): Promise<ESLintConfigGenAddonResult>;
117
}
118
119
/**
120
* Creates the import globals addon for a Nuxt instance
121
* @param nuxt - Nuxt instance to extract imports from
122
* @returns Configured addon for import globals
123
*/
124
function createAddonGlobals(nuxt: Nuxt): ImportGlobalsAddon;
125
```
126
127
### Custom Addon Development
128
129
Creating custom addons for extending ESLint configuration.
130
131
```typescript { .api }
132
/**
133
* Example custom addon for TypeScript-specific rules
134
*/
135
const typescriptAddon: ESLintConfigGenAddon = {
136
name: 'typescript-strict',
137
async getConfigs() {
138
return {
139
imports: [
140
{ from: '@typescript-eslint/eslint-plugin', name: 'default', as: 'tsPlugin' }
141
],
142
configs: [
143
`{
144
name: 'typescript-strict',
145
files: ['**/*.ts', '**/*.tsx'],
146
plugins: { '@typescript-eslint': tsPlugin },
147
rules: {
148
'@typescript-eslint/no-any': 'error',
149
'@typescript-eslint/strict-boolean-expressions': 'error'
150
}
151
}`
152
]
153
}
154
}
155
}
156
```
157
158
**Usage Examples:**
159
160
```typescript
161
// Register addon through hook in nuxt.config.ts
162
export default defineNuxtConfig({
163
modules: ['@nuxt/eslint'],
164
hooks: {
165
'eslint:config:addons': (addons) => {
166
// Add custom Vue 3 composition API rules
167
addons.push({
168
name: 'vue3-composition',
169
getConfigs() {
170
return {
171
imports: [
172
{ from: 'eslint-plugin-vue', name: 'default', as: 'vuePlugin' }
173
],
174
configs: [
175
`{
176
name: 'vue3-composition-rules',
177
files: ['**/*.vue'],
178
plugins: { vue: vuePlugin },
179
rules: {
180
'vue/prefer-composition-api': 'error',
181
'vue/no-deprecated-v-on-native-modifier': 'error'
182
}
183
}`
184
]
185
}
186
}
187
})
188
189
// Add custom import sorting rules
190
addons.push({
191
name: 'import-sorting',
192
getConfigs() {
193
return {
194
imports: [
195
{ from: 'eslint-plugin-import', name: 'default', as: 'importPlugin' }
196
],
197
configs: [
198
`{
199
name: 'import-sorting',
200
plugins: { import: importPlugin },
201
rules: {
202
'import/order': ['error', {
203
'groups': ['builtin', 'external', 'internal', 'parent', 'sibling'],
204
'newlines-between': 'always'
205
}]
206
}
207
}`
208
]
209
}
210
}
211
})
212
}
213
}
214
})
215
```
216
217
### Addon Registration Process
218
219
The addon system follows a specific lifecycle during config generation:
220
221
1. **Default Addons**: Built-in addons (like import globals) are registered
222
2. **Hook Execution**: `eslint:config:addons` hook is called with addon array
223
3. **Addon Processing**: Each addon's `getConfigs()` method is executed
224
4. **Import Resolution**: Import paths are resolved relative to config location
225
5. **Config Merging**: Generated configurations are merged into final config
226
6. **Code Generation**: Final ESLint config code is generated and written
227
228
### Advanced Addon Patterns
229
230
```typescript { .api }
231
/**
232
* Conditional addon that applies different rules based on environment
233
*/
234
const environmentAddon: ESLintConfigGenAddon = {
235
name: 'environment-specific',
236
async getConfigs() {
237
const isDev = process.env.NODE_ENV === 'development'
238
239
return {
240
configs: [
241
`{
242
name: 'environment-rules',
243
rules: {
244
'no-console': ${isDev ? '"warn"' : '"error"'},
245
'no-debugger': ${isDev ? '"warn"' : '"error"'}
246
}
247
}`
248
]
249
}
250
}
251
}
252
253
/**
254
* Dynamic addon that reads configuration from external file
255
*/
256
const dynamicAddon: ESLintConfigGenAddon = {
257
name: 'dynamic-config',
258
async getConfigs() {
259
const configPath = resolve('./eslint.custom.json')
260
const customConfig = await readFile(configPath, 'utf-8').catch(() => null)
261
262
if (!customConfig) return undefined
263
264
return {
265
configs: [
266
`// Custom configuration from ${configPath}`,
267
customConfig
268
]
269
}
270
}
271
}
272
```
273
274
## Integration Points
275
276
The extensibility system integrates with several parts of the module:
277
278
- **Config Generation**: Addons contribute to the generated ESLint configuration
279
- **Import System**: Addon imports are resolved and included in the config file
280
- **Type Generation**: TypeScript declarations are updated to include addon types
281
- **DevTools**: Custom configurations appear in the ESLint config inspector
282
283
## Best Practices
284
285
When developing custom addons:
286
287
1. **Unique Names**: Use descriptive, unique names to avoid conflicts
288
2. **Error Handling**: Handle errors gracefully in `getConfigs()` methods
289
3. **Conditional Logic**: Use environment checks for dynamic configuration
290
4. **Import Resolution**: Ensure imported modules are available in the project
291
5. **Documentation**: Document custom rules and configurations clearly