Skip to content
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: Plugin flat config migration guide #17640

Merged
merged 7 commits into from Oct 16, 2023
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
238 changes: 238 additions & 0 deletions docs/src/extend/plugin-migration-flat-config.md
@@ -0,0 +1,238 @@
---
title: Plugin Migration to Flat Config
eleventyNavigation:
key: plugin flat config
parent: create plugins
title: Migration to Flat Config
order: 4

---

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.

## Recommended Plugin Structure

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:

```js
const plugin = {
configs: {},
rules: {},
processors: {}
};

export default plugin;
```

This structure allows the most flexibility when making other changes discussed on this page.

## Migrating Rules for Flat Config

No changes are necessary for the `rules` key in your plugin. Everything works the same as with the old configuration system.

## Migrating Processors for Flat Config

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 a valid identifer (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:
nzakas marked this conversation as resolved.
Show resolved Hide resolved

```js
const plugin = {
configs: {},
rules: {},
processors: {

// no longer supported
".md": {
preprocess() {},
postprocess() {}
}
}
};

export default plugin;
```

The name `".md"` is no longer valid for a processor, so it must be replaced with a valid identifier such as `markdown`:

```js
const plugin = {
configs: {},
rules: {},
processors: {

// works in both old and new config systems
"markdown": {
preprocess() {},
postprocess() {}
}
}
};

export default plugin;
```

In order to use this renamed processor, you'll also need to manually specify it inside of a config, such as:

```js
import example from "eslint-plugin-example";

export default [
{
plugins: {
example
},
processor: "example/markdown"
}
];
```

You should update your plugin's documentation to advise your users if you have renamed a file extension-named processor.

## Migrating Configs for Flat Config

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`:

```js
// plugin name: eslint-plugin-example
module.exports = {
configs: {

// the config referenced by example/recommended
recommended: {
plugins: ["example"],
rules: {
"example/rule1": "error",
"example/rule2": "error"
}
}
},
rules: {
rule1: {},
rule2: {};
}
};
```

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:

```js
const plugin = {
configs: {},
rules: {},
processors: {}
};

// assign configs here so we can reference `plugin`
Object.assign(plugin.configs, {
recommended: {
plugins: {
example: plugin
},
rules: {
"example/rule1": "error",
"example/rule2": "error"
}
}
})

export default plugin;
```

Your users can then use this exported config like this:

```js
import example from "eslint-plugin-example";

export default [

// use recommended config
example.configs.recommended,

// and provide your own overrides
{
rules: {
"example/rule1": "warn"
}
}
];
```

You should update our documentation so your plugin users know how to reference the exported configs.

## Migrating Environments for Flat Config

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:

```js
// plugin name: eslint-plugin-example
module.exports = {
environments: {
mocha: {
globals: {
it: true,
xit: true,
describe: true,
xdescribe: true
}
}
},
rules: {
rule1: {},
rule2: {};
}
};
```

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:

```js
const plugin = {
configs: {},
rules: {},
processors: {}
};

// assign configs here so we can reference `plugin`
Object.assign(plugin.configs, {
mocha: {
languageOptions: {
globals: {
it: "writeable",
xit: "writeable",
describe: "writeable",
xdescribe: "writeable"
}
}
}
})

export default plugin;
```

Your users can then use this exported config like this:

```js
import example from "eslint-plugin-example";

export default [

// use the mocha globals
example.configs.mocha,

// and provide your own overrides
{
languageOptions: {
globals: {
it: "readonly"
}
}
}
];
```

You should update your documentation so your plugin users know how to reference the exported configs.

## Further Reading

* [Overview of the flat config file format blog post](https://eslint.org/blog/2022/08/new-config-system-part-2/)
* [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/)