@@ -42,14 +42,19 @@ const indent = inferIndent(rawPkgJson)
42
42
const pkg = JSON . parse ( rawPkgJson )
43
43
44
44
// 1. check for existing config files
45
- // `.eslintrc.*`, `eslintConfig` in `package.json`
45
+ // `.eslintrc.*`, `eslint.config.*` and ` eslintConfig` in `package.json`
46
46
// ask if wanna overwrite?
47
-
48
- // https://eslint.org/docs/latest/user-guide/configuring/configuration-files#configuration-file-formats
49
- // The experimental `eslint.config.js` isn't supported yet
50
- const eslintConfigFormats = [ 'js' , 'cjs' , 'yaml' , 'yml' , 'json' ]
51
- for ( const fmt of eslintConfigFormats ) {
52
- const configFileName = `.eslintrc.${ fmt } `
47
+ const eslintConfigFormats = [
48
+ '.eslintrc.js' ,
49
+ '.eslintrc.cjs' ,
50
+ '.eslintrc.yaml' ,
51
+ '.eslintrc.yml' ,
52
+ '.eslintrc.json' ,
53
+ 'eslint.config.js' ,
54
+ 'eslint.config.mjs' ,
55
+ 'eslint.config.cjs'
56
+ ]
57
+ for ( const configFileName of eslintConfigFormats ) {
53
58
const fullConfigPath = path . resolve ( cwd , configFileName )
54
59
if ( existsSync ( fullConfigPath ) ) {
55
60
const { shouldRemove } = await prompt ( {
@@ -88,7 +93,39 @@ if (pkg.eslintConfig) {
88
93
}
89
94
}
90
95
91
- // 2. Check Vue
96
+ // 2. Config format
97
+ let configFormat
98
+ try {
99
+ const eslintVersion = requireInCwd ( 'eslint/package.json' ) . version
100
+ console . info ( dim ( `Detected ESLint version: ${ eslintVersion } ` ) )
101
+ const [ major , minor ] = eslintVersion . split ( '.' )
102
+ if ( parseInt ( major ) >= 9 ) {
103
+ configFormat = 'flat'
104
+ } else if ( parseInt ( major ) === 8 && parseInt ( minor ) >= 21 ) {
105
+ throw eslintVersion
106
+ } else {
107
+ configFormat = 'eslintrc'
108
+ }
109
+ } catch ( e ) {
110
+ const anwsers = await prompt ( {
111
+ type : 'select' ,
112
+ name : 'configFormat' ,
113
+ message : 'Which configuration file format should be generated?' ,
114
+ choices : [
115
+ {
116
+ name : 'flat' ,
117
+ message : 'eslint.config.js (a.k.a. Flat Config, the new default)'
118
+ } ,
119
+ {
120
+ name : 'eslintrc' ,
121
+ message : `.eslintrc.cjs (deprecated with ESLint v9.0.0)`
122
+ } ,
123
+ ]
124
+ } )
125
+ configFormat = anwsers . configFormat
126
+ }
127
+
128
+ // 3. Check Vue
92
129
// Not detected? Choose from Vue 2 or 3
93
130
// TODO: better support for 2.7 and vue-demi
94
131
let vueVersion
@@ -108,7 +145,7 @@ try {
108
145
vueVersion = anwsers . vueVersion
109
146
}
110
147
111
- // 3 . Choose a style guide
148
+ // 4 . Choose a style guide
112
149
// - Error Prevention (ESLint Recommended)
113
150
// - Standard
114
151
// - Airbnb
@@ -132,10 +169,10 @@ const { styleGuide } = await prompt({
132
169
]
133
170
} )
134
171
135
- // 4 . Check TypeScript
136
- // 4 .1 Allow JS?
137
- // 4 .2 Allow JS in Vue?
138
- // 4 .3 Allow JSX (TSX, if answered no in 4 .1) in Vue?
172
+ // 5 . Check TypeScript
173
+ // 5 .1 Allow JS?
174
+ // 5 .2 Allow JS in Vue?
175
+ // 5 .3 Allow JSX (TSX, if answered no in 5 .1) in Vue?
139
176
let hasTypeScript = false
140
177
const additionalConfig = { }
141
178
try {
@@ -200,7 +237,7 @@ if (hasTypeScript && styleGuide !== 'default') {
200
237
}
201
238
}
202
239
203
- // 5 . If Airbnb && !TypeScript
240
+ // 6 . If Airbnb && !TypeScript
204
241
// Does your project use any path aliases?
205
242
// Show [snippet prompts](https://github.com/enquirer/enquirer#snippet-prompt) for the user to input aliases
206
243
if ( styleGuide === 'airbnb' && ! hasTypeScript ) {
@@ -255,7 +292,7 @@ if (styleGuide === 'airbnb' && !hasTypeScript) {
255
292
}
256
293
}
257
294
258
- // 6 . Do you need Prettier to format your codebase?
295
+ // 7 . Do you need Prettier to format your codebase?
259
296
const { needsPrettier } = await prompt ( {
260
297
type : 'toggle' ,
261
298
disabled : 'No' ,
@@ -266,6 +303,8 @@ const { needsPrettier } = await prompt({
266
303
267
304
const { pkg : pkgToExtend , files } = createConfig ( {
268
305
vueVersion,
306
+ configFormat,
307
+
269
308
styleGuide,
270
309
hasTypeScript,
271
310
needsPrettier,
@@ -291,6 +330,8 @@ for (const [name, content] of Object.entries(files)) {
291
330
writeFileSync ( fullPath , content , 'utf-8' )
292
331
}
293
332
333
+ const configFilename = configFormat === 'flat' ? 'eslint.config.js' : '.eslintrc.cjs'
334
+
294
335
// Prompt: Run `npm install` or `yarn` or `pnpm install`
295
336
const userAgent = process . env . npm_config_user_agent ?? ''
296
337
const packageManager = / p n p m / . test ( userAgent ) ? 'pnpm' : / y a r n / . test ( userAgent ) ? 'yarn' : 'npm'
@@ -300,7 +341,7 @@ const lintCommand = packageManager === 'npm' ? 'npm run lint' : `${packageManage
300
341
301
342
console . info (
302
343
'\n' +
303
- `${ bold ( yellow ( 'package.json' ) ) } and ${ bold ( blue ( '.eslintrc.cjs' ) ) } have been updated.\n` +
344
+ `${ bold ( yellow ( 'package.json' ) ) } and ${ bold ( blue ( configFilename ) ) } have been updated.\n` +
304
345
`Now please run ${ bold ( green ( installCommand ) ) } to re-install the dependencies.\n` +
305
346
`Then you can run ${ bold ( green ( lintCommand ) ) } to lint your files.`
306
347
)
0 commit comments