-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: Config Migration Guide #17230
docs: Config Migration Guide #17230
Changes from 6 commits
0226f89
4131c84
a6d4e98
affb592
985fa82
7534a3b
824f8cb
c53e236
1a05380
8927341
bde1af1
4c49578
293b0f3
a8ef90f
80be3e9
d1b4f27
ff8aa3a
9afc4dd
615d39d
bb4c6e9
0059b3c
f34ce54
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,365 @@ | ||
--- | ||
title: Configuration Migration Guide | ||
eleventyNavigation: | ||
key: migration guide | ||
parent: configure | ||
title: Configuration Migration Guide | ||
order: 8 | ||
--- | ||
|
||
This guide provides an overview of how you can migrate your ESLint configuration file from the `.eslintrc` format to the new configuration file format, `eslint.config.js`. | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
To learn more about the `eslint.config.js` file format, refer to [this blog post](https://eslint.org/blog/2022/08/new-config-system-part-2/). | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
For reference information on these configuration formats, refer to the following documentation: | ||
|
||
* [`.eslintrc` configuration files](configuration-files) | ||
* [`eslint.config.js` configuration files](configuration-files-new) | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Start Using `eslint.config.js` | ||
|
||
As of ESLint v9.0.0, the `eslint.config.js` file format is the default configuration file format. If you are using ESLint v9.0.0 or later, you can start using the `eslint.config.js` file format without any additional configuration. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's a bit misleading to me - eslint v9 has not been released. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the intention is for this guide to be published when v9 comes out. Please correct me if I'm wrong, and I can adjust the text. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll release this prior to v9 to encourage people to start the transition. |
||
|
||
To use `eslint.config.js` with ESLint v8, place a `eslint.config.js` file in the root of your project **or** set an `ESLINT_USE_FLAT_CONFIG` environment variable to `true`. | ||
|
||
## Key Differences between Configuration Formats | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
A few of the most notable differences between the `.eslintrc` and `eslint.config.js` formats are the following: | ||
|
||
### Importing Plugins and Custom Parsers | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To me, the key difference is that in eslintrc files, plugins are specified by a string and loaded from a package by ESLint itself. On the other hand, with the flat config, it's the config file that is responsible for loading a plugin as an object (with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rephrased here ff8aa3a |
||
|
||
#### .eslintrc | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be helpful to summarize the difference under each header and then show the examples without headers. Maybe something like:
|
||
|
||
String-based import system with the `plugins` property to load plugins and `extends` to load configurations from the plugins. | ||
|
||
```javascript | ||
// .eslintrc.js | ||
|
||
{ | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// ...other config | ||
plugins: ["jsdoc"], | ||
rules: { | ||
"jsdoc/require-description": "error", | ||
"jsdoc/check-values": "error" | ||
} | ||
// ...other config | ||
} | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
#### eslint.config.js | ||
|
||
Uses CommonJS `requires()` or ESModule `import` to load plugins and custom parsers. | ||
|
||
```javascript | ||
// eslint.config.js | ||
|
||
import jsdoc from "eslint-plugin-jsdoc"; | ||
|
||
export default [ | ||
{ | ||
files: ["**/*.js"], | ||
plugins: { | ||
jsdoc: jsdoc | ||
}, | ||
rules: { | ||
"jsdoc/require-description": "error", | ||
"jsdoc/check-values": "error" | ||
} | ||
} | ||
]; | ||
``` | ||
|
||
### Custom Parsers | ||
|
||
#### .eslintrc | ||
|
||
Importing a custom parser is very similar to importing a plugin. However, a parser must be a separate module. | ||
|
||
```javascript | ||
// .eslintrc.js | ||
|
||
{ | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// ...other config | ||
parser: "@babel/eslint-parser", | ||
// ...other config | ||
} | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
#### eslint.config.js | ||
|
||
To import a custom parser, import the parser as a module. Then assign it to the `languageOptions.parser` property of a configuration object: | ||
|
||
```javascript | ||
// eslint.config.js | ||
|
||
import babelParser from "@babel/eslint-parser"; | ||
|
||
export default [ | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lines 107-113 are missing one indentation space. Can you check, please? |
||
// ...other config | ||
languageOptions: { | ||
parser: babelParser | ||
} | ||
// ...other config | ||
} | ||
]; | ||
``` | ||
|
||
### Glob-Based Configs | ||
|
||
#### .eslintrc | ||
|
||
By default, .`eslintrc` files lint all files (except those covered by `.gitignore`) in the directory in which they’re placed and its child directories: | ||
|
||
```javascript | ||
// .eslintrc.js | ||
|
||
module.exports = { | ||
// ...other config | ||
rules: { | ||
semi: ["warn", "always"] | ||
} | ||
}; | ||
``` | ||
|
||
If you want to have different configurations for different file glob patterns, you can specify them in the `overrides` property: | ||
|
||
```javascript | ||
// .eslintrc.js | ||
|
||
module.exports = { | ||
// ...other config | ||
extends: "eslint:recommended", | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
overrides: [ | ||
{ | ||
files: ["src/**/*"], | ||
rules: { | ||
semi: ["warn", "always"] | ||
} | ||
}, | ||
{ | ||
files:["test/**/*"], | ||
rules: { | ||
"no-console": "off" | ||
} | ||
} | ||
] | ||
}; | ||
``` | ||
|
||
#### eslint.config.js | ||
|
||
By default, `eslint.config.js` files support different glob pattern-based configs in exported array. You can include the glob pattern in a config object's `files` property. If you don't specify a `files` property, the config defaults to the glob pattern `"**/*.{js,mjs,cjs}"`. | ||
|
||
Basically, all configuration in the `eslint.config.js` file is like the .`eslintrc` `overrides` property. | ||
|
||
Here is a configuration with the default glob pattern: | ||
|
||
```javascript | ||
// eslint.config.js | ||
|
||
import js from "@eslint/js"; | ||
|
||
export default [ | ||
js.configs.recommended, // Recommended config applied to all files | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Override the recommended config | ||
{ | ||
rules: { | ||
indent: ["error", 2], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lines 174 and 175 are missing one indentation space. |
||
"no-unused-vars": "warn" | ||
} | ||
// ...other configuration | ||
} | ||
]; | ||
``` | ||
|
||
An example configuration supporting multiple configs for different glob patterns: | ||
|
||
```javascript | ||
// eslint.config.js | ||
|
||
import js from "@eslint/js"; | ||
|
||
export default [ | ||
js.configs.recommended, // Recommended config applied to all files | ||
// File-pattern specific overrides | ||
{ | ||
files: ["src/**/*", "test/**/*"], | ||
rules: { | ||
semi: ["warn", "always"] | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
}, | ||
{ | ||
files:["test/**/*"], | ||
rules: { | ||
"no-console": "off" | ||
} | ||
} | ||
// ...other configurations | ||
]; | ||
``` | ||
|
||
### Configuring Language Options | ||
|
||
#### .eslintrc | ||
|
||
In `.eslintrc` files, you configure various language options across the `env`, `globals` and `parserOptions` properties. | ||
|
||
Global variables for specific runtimes (e.g `document` for browser JavaScript and `process` for Node.js ) are configured with the `env` property. | ||
|
||
```javascript | ||
// .eslintrc | ||
|
||
module.exports = { | ||
env: { | ||
browser: true, | ||
}, | ||
globals: { | ||
myCustomGlobal: "readonly", | ||
}, | ||
parserOptions: { | ||
ecmaVersion: 2022, | ||
sourceType: "module" | ||
} | ||
// ...other config | ||
} | ||
``` | ||
|
||
#### eslint.config.js | ||
|
||
In the `eslint.config.js`, the `globals`, and `parserOptions` are consolidated under the `languageOptions` key. | ||
|
||
There is no longer the `env` property in `eslint.config.js`. 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 all globals: | ||
|
||
```javascript | ||
// eslint.config.js | ||
|
||
import globals from "globals"; | ||
|
||
export default [ | ||
{ | ||
languageOptions: { | ||
globals: { | ||
...globals.browser, | ||
myCustomGlobal: "readonly" | ||
}, | ||
parserOptions: { | ||
ecmaVersion: 2022, | ||
sourceType: "module" | ||
} | ||
} | ||
// ...other config | ||
} | ||
]; | ||
``` | ||
|
||
### Predefined Configs | ||
|
||
#### .eslintrc | ||
|
||
To use predefined configs, use the `extends` property: | ||
|
||
```javascript | ||
// .eslintrc.js | ||
|
||
module.exports = { | ||
// ...other config | ||
extends: "eslint:recommended", | ||
rules: { | ||
semi: ["warn", "always"] | ||
}, | ||
// ...other config | ||
} | ||
``` | ||
|
||
ESLint comes with two predefined configs: | ||
|
||
* `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: | ||
|
||
```javascript | ||
// .eslintrc.js | ||
|
||
module.exports = { | ||
// ...other config | ||
extends: ["eslint:recommended", "./custom-config.js", "eslint-config-my-config"], | ||
rules: { | ||
semi: ["warn", "always"] | ||
}, | ||
// ...other config | ||
} | ||
``` | ||
|
||
#### eslint.config.js | ||
|
||
Predefined configs are imported from separate modules into `eslint.config.js` 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: | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```shell | ||
npm install @eslint/js -D | ||
``` | ||
|
||
You can add each of these configs to the exported array or expose specific rules from them. | ||
|
||
You must import the modules for local config files and npm package configs with `eslint.config.js`: | ||
|
||
```javascript | ||
// eslint.config.js | ||
|
||
import js from "@eslint/js"; | ||
import customConfig from "./custom-config.js"; | ||
import myConfig from "eslint-config-my-config"; | ||
|
||
export default [ | ||
js.configs.recommended, | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
customConfig, | ||
myConfig, | ||
{ | ||
rules: { | ||
semi: ["warn", "always"] | ||
}, | ||
// ...other config | ||
} | ||
]; | ||
``` | ||
|
||
Note that because you are just importing JavaScript modules, you can mutate the config objects before exporting them. For example, you might want to have a certain config object only apply to your test files: | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```javascript | ||
// eslint.config.js | ||
|
||
import js from "@eslint/js"; | ||
import customTestConfig from "./custom-test-config.js"; | ||
|
||
export default [ | ||
js.configs.recommended, | ||
{ | ||
...customTestConfig, | ||
files: ["**/*.test.js"], | ||
}, | ||
]; | ||
``` | ||
|
||
## Things That Haven’t Changed between Configuration File Formats | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to reviewer: other notable things which should be highlighted? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should put this section first, to let people know "these are the things you don't have to worry about". I think it's also helpful to point out that |
||
|
||
While all the above mentioned features have changed from `.eslintrc` to `eslint.config.js` configurations, the following has stayed the same: | ||
|
||
* Syntax for adding rules | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean syntax for configuring rules? You don't use "syntax" elsewhere, so maybe just "Rule configuration"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah i meant 'adding rules to the configuration file', so i think saying 'Rule configuration' expresses that more concisely. |
||
* Processors | ||
* All functionality. Just the way to configure it has changed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what "all functionality" means here. I think we can remove this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. by this, i mean "how ESLint lints files and reports errors". just the way to set up the configuration has changed. i'll play w the phrasing a bit here. |
||
* The CLI | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as stated in the rfc, the following cli options will be no longer supported:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added new CLI changes section |
||
|
||
## TypeScript Types for eslint.config.js | ||
|
||
You can see the TypeScript types for the eslint.config.js file format in the DefinitelyTyped project. The interface for the objects in the config’s array is called the `FlatConfig`. | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
You can view the type definitions in the [DefinitelyTyped repository on Github](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eslint/index.d.ts). | ||
|
||
## Further Reading | ||
|
||
* [Overview of the eslint.config.js file format blog post](https://eslint.org/blog/2022/08/new-config-system-part-2/) | ||
bpmutter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* [API usage of new configuration system blog post](https://eslint.org/blog/2022/08/new-config-system-part-3/) | ||
* [Background to new configuration system blog post](https://eslint.org/blog/2022/08/new-config-system-part-1/) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The user guide lists migration instructions for all major versions up to 8.0.0. I was thinking that in order to maintain the current convention, this file should be named
migrating-to-9.0.0.md
ormigrate-to-9.0.0.md
.I can't say if it would be good to add a link to this new guide now or wait until version 9.0.0 is released.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would defer to the ESLint team on this naming and framing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fasttime this would separate from the major version migration guides as it will span multiple versions.