Skip to content

Commit b65a80a

Browse files
feat(eslint-plugin): new nuxt-config-keys-order rule (#491)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent cc5a568 commit b65a80a

File tree

10 files changed

+506
-31
lines changed

10 files changed

+506
-31
lines changed

Diff for: docs/nuxt.config.ts

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
export default defineNuxtConfig({
22
extends: '@nuxt/ui-pro',
33

4-
routeRules: {
5-
'/guide': { redirect: '/guide/getting-started' },
6-
},
7-
8-
site: {
9-
url: 'https://eslint.nuxt.com',
10-
},
11-
124
modules: [
135
'@nuxt/image',
146
'@nuxt/content',
@@ -20,6 +12,18 @@ export default defineNuxtConfig({
2012
'nuxt-og-image',
2113
],
2214

15+
$production: {
16+
nitro: {
17+
experimental: {
18+
wasm: true,
19+
},
20+
},
21+
},
22+
23+
site: {
24+
url: 'https://eslint.nuxt.com',
25+
},
26+
2327
colorMode: {
2428
preference: 'dark',
2529
},
@@ -28,6 +32,12 @@ export default defineNuxtConfig({
2832
icons: ['heroicons', 'simple-icons', 'ph'],
2933
},
3034

35+
routeRules: {
36+
'/guide': { redirect: '/guide/getting-started' },
37+
},
38+
39+
compatibilityDate: '2024-09-01',
40+
3141
nitro: {
3242
prerender: {
3343
routes: ['/api/search.json'],
@@ -46,14 +56,4 @@ export default defineNuxtConfig({
4656
}
4757
},
4858
},
49-
50-
$production: {
51-
nitro: {
52-
experimental: {
53-
wasm: true,
54-
},
55-
},
56-
},
57-
58-
compatibilityDate: '2024-09-01',
5959
})

Diff for: packages/eslint-config/src/flat/configs/nuxt.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,17 @@ export default function nuxt(options: NuxtESLintConfigOptions): Linter.Config[]
1515
...(dirs.components?.map(componentsDir => join(componentsDir, `**/*.server.${GLOB_EXTS}`)) || []),
1616
].sort()
1717

18+
const {
19+
sortConfigKeys = !!(options.features?.stylistic),
20+
} = options.features?.nuxt || {}
21+
1822
const configs: Linter.Config[] = []
1923

2024
configs.push({
21-
name: 'nuxt/configs',
25+
name: 'nuxt/setup',
26+
plugins: {
27+
nuxt: nuxtPlugin,
28+
},
2229
languageOptions: {
2330
globals: {
2431
// Nuxt's runtime globals
@@ -38,13 +45,22 @@ export default function nuxt(options: NuxtESLintConfigOptions): Linter.Config[]
3845

3946
configs.push({
4047
name: 'nuxt/rules',
41-
plugins: {
42-
nuxt: nuxtPlugin,
43-
},
4448
rules: {
4549
'nuxt/prefer-import-meta': 'error',
4650
},
4751
})
4852

53+
if (sortConfigKeys) {
54+
configs.push({
55+
name: 'nuxt/sort-config',
56+
files: [
57+
'**/nuxt.config.?([cm])[jt]s?(x)',
58+
],
59+
rules: {
60+
'nuxt/nuxt-config-keys-order': 'error',
61+
},
62+
})
63+
}
64+
4965
return configs
5066
}

Diff for: packages/eslint-config/src/flat/types.ts

+14
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ export interface ToolingOptions {
2323
jsdoc?: boolean
2424
}
2525

26+
export interface NuxtSpecificOptions {
27+
/**
28+
* Sort keys in nuxt.config to maintain a consistent order
29+
*
30+
* @default true when `features.stylistic` is enabled
31+
*/
32+
sortConfigKeys?: boolean
33+
}
34+
2635
export interface NuxtESLintFeaturesOptions {
2736
/**
2837
* Setup basic JavaScript, TypeScript and Vue plugins and rules.
@@ -49,6 +58,11 @@ export interface NuxtESLintFeaturesOptions {
4958
*/
5059
stylistic?: boolean | StylisticCustomizeOptions<true>
5160

61+
/**
62+
* Options for Nuxt specific rules
63+
*/
64+
nuxt?: NuxtSpecificOptions
65+
5266
/**
5367
* Enable TypeScript support. Can also be an object to config the options.
5468
*

Diff for: packages/eslint-config/src/flat/utils.ts

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function resolveOptions(
3434
stylistic: false,
3535
typescript: isPackageExists('typescript'),
3636
tooling: false,
37+
nuxt: {},
3738
...config.features,
3839
},
3940
dirs,

Diff for: packages/eslint-config/test/__snapshots__/flat-compose.test.ts.snap

+103-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ exports[`flat config composition > custom src dirs 1`] = `
5757
"name": "nuxt/import/rules",
5858
},
5959
{
60-
"name": "nuxt/configs",
60+
"name": "nuxt/setup",
6161
},
6262
{
6363
"files": [
@@ -148,7 +148,7 @@ exports[`flat config composition > empty 1`] = `
148148
"name": "nuxt/import/rules",
149149
},
150150
{
151-
"name": "nuxt/configs",
151+
"name": "nuxt/setup",
152152
},
153153
{
154154
"files": [
@@ -185,7 +185,7 @@ exports[`flat config composition > empty 1`] = `
185185
exports[`flat config composition > non-standalone 1`] = `
186186
[
187187
{
188-
"name": "nuxt/configs",
188+
"name": "nuxt/setup",
189189
},
190190
{
191191
"files": [
@@ -218,3 +218,103 @@ exports[`flat config composition > non-standalone 1`] = `
218218
},
219219
]
220220
`;
221+
222+
exports[`flat config composition > with stylistic 1`] = `
223+
[
224+
{
225+
"ignores": [
226+
"**/node_modules",
227+
"**/*.iml",
228+
"**/.idea",
229+
"**/*.log",
230+
"**/.nuxt",
231+
"**/.output",
232+
"**/.yarn/cache",
233+
"**/.yarn/*state*",
234+
"**/dist",
235+
"**/.eslintcache",
236+
],
237+
"name": "gitignore",
238+
},
239+
{
240+
"ignores": [
241+
"**/dist",
242+
"**/node_modules",
243+
"**/.nuxt",
244+
"**/.output",
245+
"**/.vercel",
246+
"**/.netlify",
247+
"**/public",
248+
],
249+
},
250+
{
251+
"name": "nuxt/javascript",
252+
},
253+
{
254+
"name": "nuxt/typescript/setup",
255+
},
256+
{
257+
"files": [
258+
"**/*.ts",
259+
"**/*.tsx",
260+
"**/*.mts",
261+
"**/*.cts",
262+
"**/*.vue",
263+
],
264+
"name": "nuxt/typescript/rules",
265+
},
266+
{
267+
"name": "nuxt/vue/setup",
268+
},
269+
{
270+
"files": [
271+
"**/*.vue",
272+
],
273+
"name": "nuxt/vue/rules",
274+
},
275+
{
276+
"name": "nuxt/import/rules",
277+
},
278+
{
279+
"name": "nuxt/setup",
280+
},
281+
{
282+
"files": [
283+
"app/components/**/*.server.{js,ts,jsx,tsx,vue}",
284+
"app/layouts/**/*.{js,ts,jsx,tsx,vue}",
285+
"app/pages/**/*.{js,ts,jsx,tsx,vue}",
286+
"components/**/*.server.{js,ts,jsx,tsx,vue}",
287+
"layouts/**/*.{js,ts,jsx,tsx,vue}",
288+
"pages/**/*.{js,ts,jsx,tsx,vue}",
289+
],
290+
"name": "nuxt/vue/single-root",
291+
},
292+
{
293+
"name": "nuxt/rules",
294+
},
295+
{
296+
"files": [
297+
"**/nuxt.config.?([cm])[jt]s?(x)",
298+
],
299+
"name": "nuxt/sort-config",
300+
},
301+
{
302+
"name": "nuxt/stylistic",
303+
},
304+
{
305+
"files": [
306+
"app.{js,ts,jsx,tsx,vue}",
307+
"app/app.{js,ts,jsx,tsx,vue}",
308+
"app/components/*/**/*.{js,ts,jsx,tsx,vue}",
309+
"app/error.{js,ts,jsx,tsx,vue}",
310+
"app/layouts/**/*.{js,ts,jsx,tsx,vue}",
311+
"app/pages/**/*.{js,ts,jsx,tsx,vue}",
312+
"components/*/**/*.{js,ts,jsx,tsx,vue}",
313+
"error.{js,ts,jsx,tsx,vue}",
314+
"layouts/**/*.{js,ts,jsx,tsx,vue}",
315+
"pages/**/*.{js,ts,jsx,tsx,vue}",
316+
],
317+
"name": "nuxt/disables/routes",
318+
},
319+
]
320+
`;

Diff for: packages/eslint-config/test/flat-compose.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,15 @@ describe('flat config composition', () => {
4343
expect(getFlatConfigDigest(configs))
4444
.toMatchSnapshot()
4545
})
46+
47+
it('with stylistic', async () => {
48+
const configs = await createConfigForNuxt({
49+
features: {
50+
stylistic: true,
51+
},
52+
})
53+
54+
expect(getFlatConfigDigest(configs))
55+
.toMatchSnapshot()
56+
})
4657
})

Diff for: packages/eslint-plugin/src/rules/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { rule as preferImportMetaRule } from './prefer-import-meta'
2+
import { rule as nuxtConfigOrderKeysRule } from './nuxt-config-keys-order'
23

34
export default {
45
'prefer-import-meta': preferImportMetaRule,
6+
'nuxt-config-keys-order': nuxtConfigOrderKeysRule,
57
}

0 commit comments

Comments
 (0)