1
1
import * as fs from 'node:fs'
2
2
import * as path from 'node:path'
3
3
4
- import type { Linter } from 'eslint'
5
-
6
4
import createESLintConfig from '@vue/create-eslint-config'
7
5
8
6
import sortDependencies from './sortDependencies'
@@ -15,29 +13,23 @@ export default function renderEslint(
15
13
rootDir ,
16
14
{ needsTypeScript, needsVitest, needsCypress, needsCypressCT, needsPrettier, needsPlaywright }
17
15
) {
18
- const { additionalConfig , additionalDependencies } = getAdditionalConfigAndDependencies ( {
16
+ const additionalConfigs = getAdditionalConfigs ( {
19
17
needsVitest,
20
18
needsCypress,
21
19
needsCypressCT,
22
20
needsPlaywright
23
21
} )
24
22
25
23
const { pkg, files } = createESLintConfig ( {
26
- vueVersion : '3.x' ,
27
- // we currently don't support other style guides
28
24
styleGuide : 'default' ,
29
25
hasTypeScript : needsTypeScript ,
30
26
needsPrettier,
31
27
32
- additionalConfig,
33
- additionalDependencies
28
+ additionalConfigs
34
29
} )
35
30
36
31
const scripts : Record < string , string > = {
37
- // Note that we reuse .gitignore here to avoid duplicating the configuration
38
- lint : needsTypeScript
39
- ? 'eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore'
40
- : 'eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore'
32
+ lint : 'eslint . --fix'
41
33
}
42
34
43
35
// Theoretically, we could add Prettier without requring ESLint.
@@ -54,62 +46,90 @@ export default function renderEslint(
54
46
const packageJsonPath = path . resolve ( rootDir , 'package.json' )
55
47
const existingPkg = JSON . parse ( fs . readFileSync ( packageJsonPath , 'utf8' ) )
56
48
const updatedPkg = sortDependencies ( deepMerge ( deepMerge ( existingPkg , pkg ) , { scripts } ) )
57
- fs . writeFileSync ( packageJsonPath , JSON . stringify ( updatedPkg , null , 2 ) + '\n' , 'utf-8 ' )
49
+ fs . writeFileSync ( packageJsonPath , JSON . stringify ( updatedPkg , null , 2 ) + '\n' , 'utf8 ' )
58
50
59
- // write to .eslintrc.cjs , .prettierrc.json, etc.
51
+ // write to eslint.config.mjs , .prettierrc.json, .editorconfig , etc.
60
52
for ( const [ fileName , content ] of Object . entries ( files ) ) {
61
53
const fullPath = path . resolve ( rootDir , fileName )
62
- fs . writeFileSync ( fullPath , content as string , 'utf-8 ' )
54
+ fs . writeFileSync ( fullPath , content as string , 'utf8 ' )
63
55
}
64
56
}
65
57
58
+ type ConfigItemInESLintTemplate = {
59
+ importer : string
60
+ content : string
61
+ }
62
+ type AdditionalConfig = {
63
+ devDependencies : Record < string , string >
64
+ beforeVuePlugin ?: Array < ConfigItemInESLintTemplate >
65
+ afterVuePlugin ?: Array < ConfigItemInESLintTemplate >
66
+ }
67
+ type AdditionalConfigArray = Array < AdditionalConfig >
68
+
66
69
// visible for testing
67
- export function getAdditionalConfigAndDependencies ( {
70
+ export function getAdditionalConfigs ( {
68
71
needsVitest,
69
72
needsCypress,
70
73
needsCypressCT,
71
74
needsPlaywright
72
75
} ) {
73
- const additionalConfig : Linter . Config = { }
74
- const additionalDependencies = { }
76
+ const additionalConfigs : AdditionalConfigArray = [ ]
75
77
76
78
if ( needsVitest ) {
77
- additionalConfig . overrides = [
78
- {
79
- files : [ 'src/**/*.{test,spec}.{js,ts,jsx,tsx}' ] ,
80
- extends : [ 'plugin:@vitest/legacy-recommended' ]
81
- }
82
- ]
83
-
84
- additionalDependencies [ '@vitest/eslint-plugin' ] = eslintDeps [ '@vitest/eslint-plugin' ]
79
+ additionalConfigs . push ( {
80
+ devDependencies : { '@vitest/eslint-plugin' : eslintDeps [ '@vitest/eslint-plugin' ] } ,
81
+ afterVuePlugin : [
82
+ {
83
+ importer : `import pluginVitest from '@vitest/eslint-plugin'` ,
84
+ content : `
85
+ {
86
+ ...pluginVitest.configs['recommended'],
87
+ files: ['src/**/__tests__/*'],
88
+ },`
89
+ }
90
+ ]
91
+ } )
85
92
}
86
93
87
94
if ( needsCypress ) {
88
- additionalConfig . overrides = [
89
- {
90
- files : needsCypressCT
91
- ? [
92
- '**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}' ,
93
- 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}' ,
94
- 'cypress/support/**/*.{js,ts,jsx,tsx}'
95
- ]
96
- : [ 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}' , 'cypress/support/**/*.{js,ts,jsx,tsx}' ] ,
97
- extends : [ 'plugin:cypress/recommended' ]
98
- }
99
- ]
100
-
101
- additionalDependencies [ 'eslint-plugin-cypress' ] = eslintDeps [ 'eslint-plugin-cypress' ]
95
+ additionalConfigs . push ( {
96
+ devDependencies : { 'eslint-plugin-cypress' : eslintDeps [ 'eslint-plugin-cypress' ] } ,
97
+ afterVuePlugin : [
98
+ {
99
+ importer : "import pluginCypress from 'eslint-plugin-cypress/flat'" ,
100
+ content : `
101
+ {
102
+ ...pluginCypress.configs.recommended,
103
+ files: [
104
+ ${ [
105
+ ...( needsCypressCT ? [ "'**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}'," ] : [ ] ) ,
106
+ 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}' ,
107
+ 'cypress/support/**/*.{js,ts,jsx,tsx}'
108
+ ]
109
+ . map ( JSON . stringify . bind ( JSON ) )
110
+ . join ( ',\n ' ) }
111
+ ],
112
+ },`
113
+ }
114
+ ]
115
+ } )
102
116
}
103
117
104
118
if ( needsPlaywright ) {
105
- additionalConfig . overrides = [
106
- {
107
- files : [ 'e2e/**/*.{test,spec}.{js,ts,jsx,tsx}' ] ,
108
- extends : [ 'plugin:playwright/recommended' ]
109
- }
110
- ]
111
-
112
- additionalDependencies [ 'eslint-plugin-playwright' ] = eslintDeps [ 'eslint-plugin-playwright' ]
119
+ additionalConfigs . push ( {
120
+ devDependencies : { 'eslint-plugin-playwright' : eslintDeps [ 'eslint-plugin-playwright' ] } ,
121
+ afterVuePlugin : [
122
+ {
123
+ importer : "import pluginPlaywright from 'eslint-plugin-playwright'" ,
124
+ content : `
125
+ {
126
+ ...pluginPlaywright.configs['flat/recommended'],
127
+ files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'],
128
+ },`
129
+ }
130
+ ]
131
+ } )
113
132
}
114
- return { additionalConfig, additionalDependencies }
133
+
134
+ return additionalConfigs
115
135
}
0 commit comments