diff --git a/docs/src/use/configure/migration-guide.md b/docs/src/use/configure/migration-guide.md index 14680d365e5..b931244e144 100644 --- a/docs/src/use/configure/migration-guide.md +++ b/docs/src/use/configure/migration-guide.md @@ -211,7 +211,7 @@ In eslintrc files, you configure various language options across the `env`, `glo In flat config files, the `globals`, and `parserOptions` are consolidated under the `languageOptions` key; the `env` property doesn't exist. Groups of global variables for specific runtimes are imported from the [globals](https://www.npmjs.com/package/globals) npm package and included in the `globals` property. You can use the spread operator (`...`) to import multiple globals at once. -For example, here's a eslintrc file with language options: +For example, here's an eslintrc file with language options: ```javascript // .eslintrc.js @@ -314,14 +314,14 @@ export default [ ]; ``` -### Predefined Configs +### Predefined and Shareable Configs -In eslintrc files, use the `extends` property to use predefined configs. ESLint comes with two predefined configs that you can access as strings: +In eslintrc files, use the `extends` property to use predefined and shareable configs. ESLint comes with two predefined configs that you can access as strings: * `"eslint:recommended"`: the rules recommended by ESLint * `"eslint:all"`: all rules shipped with ESLint -You can also use the `extends` property to extend a custom config. Custom configs can either be paths to local config files or npm package names. +You can also use the `extends` property to extend a shareable config. Shareable configs can either be paths to local config files or npm package names. In flat config files, predefined configs are imported from separate modules into flat config files. The `recommended` and `all` rules configs are located in the [`@eslint/js`](https://www.npmjs.com/package/@eslint/js) package. You must import this package to use these configs: @@ -346,7 +346,7 @@ module.exports = { } ``` -This eslintrc file uses built-in config, local custom config, and custom config from an npm package: +This eslintrc file uses built-in config, local custom config, and shareable config from an npm package: ```javascript // .eslintrc.js @@ -400,6 +400,40 @@ export default [ ]; ``` +#### Using eslintrc Configs in Flat Config + +You may find that there's a shareable config you rely on that hasn't yet been updated to flat config format. In that case, you can use the `FlatCompat` utility to translate the eslintrc format into flat config format. First, install the `@eslint/eslintrc` package: + +```shell +npm install @eslint/eslintrc --save-dev +``` + +Then, import `FlatCompat` and create a new instance to convert an existing eslintrc config. For example, if the npm package `eslint-config-my-config` is in eslintrc format, you can write this: + +```js +import { FlatCompat } from "@eslint/eslintrc"; +import path from "path"; +import { fileURLToPath } from "url"; + +// mimic CommonJS variables -- not needed if using CommonJS +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname +}); + +export default [ + + // mimic ESLintRC-style extends + ...compat.extends("eslint-config-my-config"), +]; +``` + +This example uses the `FlatCompat#extends()` method to insert the `eslint-config-my-config` into the flat config array. + +For more information about the `FlatCompat` class, please see the [package README](https://github.com/eslint/eslintrc#usage). + ### Ignoring Files With eslintrc, you can make ESLint ignore files by creating a separate `.eslintignore` file in the root of your project. The `.eslintignore` file uses the same glob pattern syntax as `.gitignore` files. Alternatively, you can use an `ignorePatterns` property in your eslintrc file. diff --git a/lib/config/flat-config-schema.js b/lib/config/flat-config-schema.js index 7325742adfc..3922e8a94fe 100644 --- a/lib/config/flat-config-schema.js +++ b/lib/config/flat-config-schema.js @@ -227,6 +227,22 @@ class IncompatibleKeyError extends Error { } } +/** + * The error type when there's an eslintrc-style plugins array found. + */ +class IncompatiblePluginsError extends Error { + + /** + * Creates a new instance. + * @param {Array} plugins The plugins array. + */ + constructor(plugins) { + super("This appears to be in eslintrc format (array of strings) rather than flat config format (object)."); + this.messageTemplate = "eslintrc-plugins"; + this.messageData = { plugins }; + } +} + //----------------------------------------------------------------------------- // Low-Level Schemas @@ -319,6 +335,11 @@ const pluginsSchema = { throw new TypeError("Expected an object."); } + // make sure it's not an array, which would mean eslintrc-style is used + if (Array.isArray(value)) { + throw new IncompatiblePluginsError(value); + } + // second check the keys to make sure they are objects for (const key of Object.keys(value)) { diff --git a/messages/eslintrc-plugins.js b/messages/eslintrc-plugins.js new file mode 100644 index 00000000000..bb708c95b05 --- /dev/null +++ b/messages/eslintrc-plugins.js @@ -0,0 +1,24 @@ +"use strict"; + +module.exports = function({ plugins }) { + + const isArrayOfStrings = typeof plugins[0] === "string"; + + return ` +A config object has a "plugins" key defined as an array${isArrayOfStrings ? " of strings" : ""}. + +Flat config requires "plugins" to be an object in this form: + + { + plugins: { + ${isArrayOfStrings && plugins[0] ? plugins[0] : "namespace"}: pluginObject + } + } + +Please see the following page for information on how to convert your config object into the correct format: +https://eslint.org/docs/latest/use/configure/migration-guide#importing-plugins-and-custom-parsers + +If you're using a shareable config that you cannot rewrite in flat config format, then use the compatibility utility: +https://eslint.org/docs/latest/use/configure/migration-guide#using-eslintrc-configs-in-flat-config +`; +}; diff --git a/tests/lib/config/flat-config-array.js b/tests/lib/config/flat-config-array.js index 10f9c31c3d2..35888237483 100644 --- a/tests/lib/config/flat-config-array.js +++ b/tests/lib/config/flat-config-array.js @@ -1963,6 +1963,15 @@ describe("FlatConfigArray", () => { }); }); + it("should error when plugins is an array", async () => { + await assertInvalidConfig([ + { + plugins: ["foo"] + } + ], "Key \"plugins\": This appears to be in eslintrc format (array of strings) rather than flat config format (object)."); + + }); + });