Skip to content

Commit cf03104

Browse files
nzakasmdjermanovic
andauthored
feat: Improve config error messages (#17385)
* feat: Improve config error messages Includes some keys to catch known eslintrc keys when they appear in flat config. This throws a specific error that the ESLint CLI can then output a more helpful message about. fixes #17370 * Update messages/eslintrc-incompat.js Co-authored-by: Milos Djermanovic <[email protected]> * Update messages/eslintrc-incompat.js Co-authored-by: Milos Djermanovic <[email protected]> * Apply feedback --------- Co-authored-by: Milos Djermanovic <[email protected]>
1 parent 42faa17 commit cf03104

4 files changed

Lines changed: 176 additions & 1 deletion

File tree

lib/config/flat-config-schema.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,22 @@ function assertIsObject(value) {
212212
}
213213
}
214214

215+
/**
216+
* The error type when there's an eslintrc-style options in a flat config.
217+
*/
218+
class IncompatibleKeyError extends Error {
219+
220+
/**
221+
* @param {string} key The invalid key.
222+
*/
223+
constructor(key) {
224+
super("This appears to be in eslintrc format rather than flat config format.");
225+
this.messageTemplate = "eslintrc-incompat";
226+
this.messageData = { key };
227+
}
228+
}
229+
230+
215231
//-----------------------------------------------------------------------------
216232
// Low-Level Schemas
217233
//-----------------------------------------------------------------------------
@@ -438,11 +454,44 @@ const sourceTypeSchema = {
438454
}
439455
};
440456

457+
/**
458+
* Creates a schema that always throws an error. Useful for warning
459+
* about eslintrc-style keys.
460+
* @param {string} key The eslintrc key to create a schema for.
461+
* @returns {ObjectPropertySchema} The schema.
462+
*/
463+
function createEslintrcErrorSchema(key) {
464+
return {
465+
merge: "replace",
466+
validate() {
467+
throw new IncompatibleKeyError(key);
468+
}
469+
};
470+
}
471+
472+
const eslintrcKeys = [
473+
"env",
474+
"extends",
475+
"globals",
476+
"ignorePatterns",
477+
"noInlineConfig",
478+
"overrides",
479+
"parser",
480+
"parserOptions",
481+
"reportUnusedDisableDirectives",
482+
"root"
483+
];
484+
441485
//-----------------------------------------------------------------------------
442486
// Full schema
443487
//-----------------------------------------------------------------------------
444488

445489
exports.flatConfigSchema = {
490+
491+
// eslintrc-style keys that should always error
492+
...Object.fromEntries(eslintrcKeys.map(key => [key, createEslintrcErrorSchema(key)])),
493+
494+
// flat config keys
446495
settings: deepObjectAssignSchema,
447496
linterOptions: {
448497
schema: {

messages/eslintrc-incompat.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
"use strict";
2+
3+
/* eslint consistent-return: 0 -- no default case */
4+
5+
const messages = {
6+
7+
env: `
8+
A config object is using the "env" key, which is not supported in flat config system.
9+
10+
Flat config uses "languageOptions.globals" to define global variables for your files.
11+
12+
Please see the following page for information on how to convert your config object into the correct format:
13+
https://eslint.org/docs/latest/use/configure/migration-guide#configuring-language-options
14+
`,
15+
16+
extends: `
17+
A config object is using the "extends" key, which is not supported in flat config system.
18+
19+
Instead of "extends", you can include config objects that you'd like to extend from directly in the flat config array.
20+
21+
Please see the following page for more information:
22+
https://eslint.org/docs/latest/use/configure/migration-guide#predefined-configs
23+
`,
24+
25+
globals: `
26+
A config object is using the "globals" key, which is not supported in flat config system.
27+
28+
Flat config uses "languageOptions.globals" to define global variables for your files.
29+
30+
Please see the following page for information on how to convert your config object into the correct format:
31+
https://eslint.org/docs/latest/use/configure/migration-guide#configuring-language-options
32+
`,
33+
34+
ignorePatterns: `
35+
A config object is using the "ignorePatterns" key, which is not supported in flat config system.
36+
37+
Flat config uses "ignores" to specify files to ignore.
38+
39+
Please see the following page for information on how to convert your config object into the correct format:
40+
https://eslint.org/docs/latest/use/configure/migration-guide#ignoring-files
41+
`,
42+
43+
noInlineConfig: `
44+
A config object is using the "noInlineConfig" key, which is not supported in flat config system.
45+
46+
Flat config uses "linterOptions.noInlineConfig" to specify files to ignore.
47+
48+
Please see the following page for information on how to convert your config object into the correct format:
49+
https://eslint.org/docs/latest/use/configure/migration-guide#linter-options
50+
`,
51+
52+
overrides: `
53+
A config object is using the "overrides" key, which is not supported in flat config system.
54+
55+
Flat config is an array that acts like the eslintrc "overrides" array.
56+
57+
Please see the following page for information on how to convert your config object into the correct format:
58+
https://eslint.org/docs/latest/use/configure/migration-guide#glob-based-configs
59+
`,
60+
61+
parser: `
62+
A config object is using the "parser" key, which is not supported in flat config system.
63+
64+
Flat config uses "languageOptions.parser" to override the default parser.
65+
66+
Please see the following page for information on how to convert your config object into the correct format:
67+
https://eslint.org/docs/latest/use/configure/migration-guide#custom-parsers
68+
`,
69+
70+
parserOptions: `
71+
A config object is using the "parserOptions" key, which is not supported in flat config system.
72+
73+
Flat config uses "languageOptions.parserOptions" to specify parser options.
74+
75+
Please see the following page for information on how to convert your config object into the correct format:
76+
https://eslint.org/docs/latest/use/configure/migration-guide#configuring-language-options
77+
`,
78+
79+
reportUnusedDisableDirectives: `
80+
A config object is using the "reportUnusedDisableDirectives" key, which is not supported in flat config system.
81+
82+
Flat config uses "linterOptions.reportUnusedDisableDirectives" to specify files to ignore.
83+
84+
Please see the following page for information on how to convert your config object into the correct format:
85+
https://eslint.org/docs/latest/use/configure/migration-guide#linter-options
86+
`,
87+
88+
root: `
89+
A config object is using the "root" key, which is not supported in flat config system.
90+
91+
Flat configs always act as if they are the root config file, so this key can be safely removed.
92+
`
93+
};
94+
95+
module.exports = function({ key }) {
96+
97+
return messages[key].trim();
98+
};

tests/lib/config/flat-config-array.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,5 +1938,33 @@ describe("FlatConfigArray", () => {
19381938

19391939
});
19401940

1941+
describe("Invalid Keys", () => {
1942+
1943+
[
1944+
"env",
1945+
"extends",
1946+
"globals",
1947+
"ignorePatterns",
1948+
"noInlineConfig",
1949+
"overrides",
1950+
"parser",
1951+
"parserOptions",
1952+
"reportUnusedDisableDirectives",
1953+
"root"
1954+
].forEach(key => {
1955+
1956+
it(`should error when a ${key} key is found`, async () => {
1957+
await assertInvalidConfig([
1958+
{
1959+
[key]: "foo"
1960+
}
1961+
], `Key "${key}": This appears to be in eslintrc format rather than flat config format.`);
1962+
1963+
});
1964+
});
1965+
1966+
1967+
});
1968+
19411969
});
19421970
});

tests/lib/rule-tester/flat-rule-tester.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1336,7 +1336,7 @@ describe("FlatRuleTester", () => {
13361336
],
13371337
invalid: []
13381338
});
1339-
}, /Unexpected key "env" found./u);
1339+
}, /Key "env": This appears to be in eslintrc format rather than flat config format/u);
13401340
});
13411341

13421342
it("should pass-through the tester config to the rule", () => {

0 commit comments

Comments
 (0)