Skip to content

Commit 660ed3a

Browse files
nzakasmdjermanovic
andauthored
docs: Plugin flat config migration guide (#17640)
* docs: Plugin flat config migration guide Fixes #17242 * Switch exports to default * Update docs/src/extend/plugin-migration-flat-config.md Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com> * Meta information * CommonJS syntax * Backwards compatibility * Update docs/src/extend/plugin-migration-flat-config.md Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com> --------- Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
1 parent a58aa20 commit 660ed3a

File tree

1 file changed

+293
-0
lines changed

1 file changed

+293
-0
lines changed
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
---
2+
title: Plugin Migration to Flat Config
3+
eleventyNavigation:
4+
key: plugin flat config
5+
parent: create plugins
6+
title: Migration to Flat Config
7+
order: 4
8+
9+
---
10+
11+
Beginning in ESLint v9.0.0, the default configuration system will be the new flat config system. In order for your plugins to work with flat config files, you'll need to make some changes to your existing plugins.
12+
13+
## Recommended Plugin Structure
14+
15+
To make it easier to work with your plugin in the flat config system, it's recommended that you switch your existing plugin entrypoint to look like this:
16+
17+
```js
18+
const plugin = {
19+
meta: {},
20+
configs: {},
21+
rules: {},
22+
processors: {}
23+
};
24+
25+
// for ESM
26+
export default plugin;
27+
28+
// OR for CommonJS
29+
module.exports = plugin;
30+
```
31+
32+
This structure allows the most flexibility when making other changes discussed on this page.
33+
34+
## Adding Plugin Meta Information
35+
36+
With the old eslintrc configuration system, ESLint could pull information about the plugin from the package name, but with flat config, ESLint no longer has access to the name of the plugin package. To replace that missing information, you should add a `meta` key that contains at least a `name` key, and ideally, a `version` key, such as:
37+
38+
```js
39+
const plugin = {
40+
meta: {
41+
name: "eslint-plugin-example",
42+
version: "1.0.0"
43+
},
44+
configs: {},
45+
rules: {},
46+
processors: {}
47+
};
48+
49+
// for ESM
50+
export default plugin;
51+
52+
// OR for CommonJS
53+
module.exports = plugin;
54+
```
55+
56+
If your plugin is published as an npm package, the `name` and `version` should be the same as in your `package.json` file; otherwise, you can assign any value you'd like.
57+
58+
Without this meta information, your plugin will not be usable with the `--cache` and `--print-config` command line options.
59+
60+
## Migrating Rules for Flat Config
61+
62+
No changes are necessary for the `rules` key in your plugin. Everything works the same as with the old eslintrc configuration system.
63+
64+
## Migrating Processors for Flat Config
65+
66+
No changes are necessary for the `processors` key in your plugin as long as you aren't using file extension-named processors. If you have any [file extension-named processors](custom-processors#file-extension-named-processor), you must update the name to a valid identifier (numbers and letters). File extension-named processors were automatically applied in the old configuration system but are not automatically applied when using flat config. Here is an example of a file extension-named processor:
67+
68+
```js
69+
const plugin = {
70+
configs: {},
71+
rules: {},
72+
processors: {
73+
74+
// no longer supported
75+
".md": {
76+
preprocess() {},
77+
postprocess() {}
78+
}
79+
}
80+
};
81+
82+
// for ESM
83+
export default plugin;
84+
85+
// OR for CommonJS
86+
module.exports = plugin;
87+
```
88+
89+
The name `".md"` is no longer valid for a processor, so it must be replaced with a valid identifier such as `markdown`:
90+
91+
```js
92+
const plugin = {
93+
configs: {},
94+
rules: {},
95+
processors: {
96+
97+
// works in both old and new config systems
98+
"markdown": {
99+
preprocess() {},
100+
postprocess() {}
101+
}
102+
}
103+
};
104+
105+
// for ESM
106+
export default plugin;
107+
108+
// OR for CommonJS
109+
module.exports = plugin;
110+
```
111+
112+
In order to use this renamed processor, you'll also need to manually specify it inside of a config, such as:
113+
114+
```js
115+
import example from "eslint-plugin-example";
116+
117+
export default [
118+
{
119+
plugins: {
120+
example
121+
},
122+
processor: "example/markdown"
123+
}
124+
];
125+
```
126+
127+
You should update your plugin's documentation to advise your users if you have renamed a file extension-named processor.
128+
129+
## Migrating Configs for Flat Config
130+
131+
If your plugin is exporting configs that refer back to your plugin, then you'll need to update your configs to flat config format. As part of the migration, you'll need to reference your plugin directly in the `plugins` key. For example, here is an exported config in the old configuration system format for a plugin named `eslint-plugin-example`:
132+
133+
```js
134+
// plugin name: eslint-plugin-example
135+
module.exports = {
136+
configs: {
137+
138+
// the config referenced by example/recommended
139+
recommended: {
140+
plugins: ["example"],
141+
rules: {
142+
"example/rule1": "error",
143+
"example/rule2": "error"
144+
}
145+
}
146+
},
147+
rules: {
148+
rule1: {},
149+
rule2: {};
150+
}
151+
};
152+
```
153+
154+
To migrate to flat config format, you'll need to move the configs to after the definition of the `plugin` variable in the recommended plugin structure, like this:
155+
156+
```js
157+
const plugin = {
158+
configs: {},
159+
rules: {},
160+
processors: {}
161+
};
162+
163+
// assign configs here so we can reference `plugin`
164+
Object.assign(plugin.configs, {
165+
recommended: {
166+
plugins: {
167+
example: plugin
168+
},
169+
rules: {
170+
"example/rule1": "error",
171+
"example/rule2": "error"
172+
}
173+
}
174+
})
175+
176+
// for ESM
177+
export default plugin;
178+
179+
// OR for CommonJS
180+
module.exports = plugin;
181+
```
182+
183+
Your users can then use this exported config like this:
184+
185+
```js
186+
import example from "eslint-plugin-example";
187+
188+
export default [
189+
190+
// use recommended config
191+
example.configs.recommended,
192+
193+
// and provide your own overrides
194+
{
195+
rules: {
196+
"example/rule1": "warn"
197+
}
198+
}
199+
];
200+
```
201+
202+
You should update our documentation so your plugin users know how to reference the exported configs.
203+
204+
## Migrating Environments for Flat Config
205+
206+
Environments are no longer supported in flat config, and so we recommend transitioning your environments into exported configs. For example, suppose you export a `mocha` environment like this:
207+
208+
```js
209+
// plugin name: eslint-plugin-example
210+
module.exports = {
211+
environments: {
212+
mocha: {
213+
globals: {
214+
it: true,
215+
xit: true,
216+
describe: true,
217+
xdescribe: true
218+
}
219+
}
220+
},
221+
rules: {
222+
rule1: {},
223+
rule2: {};
224+
}
225+
};
226+
```
227+
228+
To migrate this environment into a config, you need to add a new key in the `plugin.configs` object that has a flat config object containing the same information, like this:
229+
230+
```js
231+
const plugin = {
232+
configs: {},
233+
rules: {},
234+
processors: {}
235+
};
236+
237+
// assign configs here so we can reference `plugin`
238+
Object.assign(plugin.configs, {
239+
mocha: {
240+
languageOptions: {
241+
globals: {
242+
it: "writeable",
243+
xit: "writeable",
244+
describe: "writeable",
245+
xdescribe: "writeable"
246+
}
247+
}
248+
}
249+
})
250+
251+
// for ESM
252+
export default plugin;
253+
254+
// OR for CommonJS
255+
module.exports = plugin;
256+
```
257+
258+
Your users can then use this exported config like this:
259+
260+
```js
261+
import example from "eslint-plugin-example";
262+
263+
export default [
264+
265+
// use the mocha globals
266+
example.configs.mocha,
267+
268+
// and provide your own overrides
269+
{
270+
languageOptions: {
271+
globals: {
272+
it: "readonly"
273+
}
274+
}
275+
}
276+
];
277+
```
278+
279+
You should update your documentation so your plugin users know how to reference the exported configs.
280+
281+
## Backwards Compatibility
282+
283+
If your plugin needs to work with both the old and new configuration systems, then you'll need to:
284+
285+
1. **Export a CommonJS entrypoint.** The old configuration system cannot load plugins that are published only in ESM format. If your source code is in ESM, then you'll need to use a bundler that can generate a CommonJS version and use the [`exports`](https://nodejs.org/api/packages.html#package-entry-points) key in your `package.json` file to ensure the CommonJS version can be found by Node.js.
286+
1. **Keep the `environments` key.** If your plugin exports custom environments, you should keep those as they are and also export the equivalent flat configs as described above. The `environments` key is ignored when ESLint is running in flat config mode.
287+
1. **Export both eslintrc and flat configs.** The `configs` key is only validated when a config is used, so you can provide both formats of configs in the `configs` key. We recommend that you append older format configs with `-legacy` to make it clear that these configs will not be supported in the future. For example, if your primary config is called `recommended` and is in flat config format, then you can also have a config named `recommended-legacy` that is the eslintrc config format.
288+
289+
## Further Reading
290+
291+
* [Overview of the flat config file format blog post](https://eslint.org/blog/2022/08/new-config-system-part-2/)
292+
* [API usage of new configuration system blog post](https://eslint.org/blog/2022/08/new-config-system-part-3/)
293+
* [Background to new configuration system blog post](https://eslint.org/blog/2022/08/new-config-system-part-1/)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy