-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Description
ESLint version
8.56.0
What problem do you want to solve?
There are long-time rule properties meta.deprecated
and meta.replacedBy
that have been intended to document when rules are deprecated and what their replacement rule(s) are. For the most part, usage would look something like this:
module.exports = { meta: { deprecated: true, replacedBy: ['replacement-rule-name'] } };
These properties are often used for generating plugin/rule documentation websites and in documentation tooling like eslint-doc-generator.
But there are some limitations to this current format.
- Simply providing the replacement rule name as a string doesn't yield much context/explanation of the replacement/deprecation.
- Some rules provide the replacement rule name with the plugin prefix as in
prefix/rule-name
while others just provide it asrule-name
, which can result in ambiguity about whether the replacement rule is in the same plugin, a different third-party plugin, or ESLint core. For third-party plugins, there's no easy way to automatically determine where their documentation is located or how to link to them.
What do you think is the correct solution?
I would like to propose an extended meta.deprecated
/ meta.replacedBy
rule property schema to reduce ambiguity and allow additional key details to be represented in it, described below as a TypeScript type for clarity:
type RuleMeta = {
deprecated:
| boolean // Existing boolean option, backwards compatible.
| string // General deprecation message, such as why the deprecation occurred. Any truthy value implies deprecated.
| {
message?: string; // General deprecation message, such as why the deprecation occurred.
url?: string; // URL to more information about this deprecation in general.
};
replacedBy:
| readonly string[] // Existing string array option of rule names, backwards compatible.
| readonly {
/**
* Plugin containing the replacement.
* Use "eslint" if the replacement is an ESLint core rule.
* Omit if the replacement is in the same plugin.
*/
plugin?:
| string // Plugin name i.e. "eslint-plugin-example" that contains the replacement rule.
| {
name?: string; // Plugin name i.e. "eslint-plugin-example" that contains the replacement rule.
url?: string; // URL to plugin documentation.
};
rule:
| string // Replacement rule name (without plugin prefix).
| {
name?: string; // Replacement rule name (without plugin prefix).
url?: string; // URL to rule documentation.
};
deprecation?: {
message?: string; // Message about this specific replacement, such as how to use/configure the replacement rule to achieve the same results as the rule being replaced.
url?: string; // URL to more information about this specific deprecation/replacement.
};
}[]
| undefined;
};
Real-world example of how this could be used based on the situation in #18053:
// lib/rules/semi.js
module.exports = {
meta: {
deprecated: {
message: 'Stylistic rules are being moved out of ESLint core.',
url: 'https://eslint.org/blog/2023/10/deprecating-formatting-rules/',
},
replacedBy: [
{
plugin: {
name: '@stylistic/js',
url: 'https://eslint.style/',
},
rule: {
name: 'semi',
url: 'https://eslint.style/rules/js/semi',
},
},
],
},
};
This data could be used by documentation websites and tooling like eslint-doc-generator to generate notices like:
semi (deprecated)
Replaced by semi from @stylistic/js.
Stylistic rules are being moved out of ESLint core. Read more.
We can also support the same meta.deprecated
and meta.replacedBy
properties on configurations and processors (the other kinds of objects exported by ESLint plugins), replacing rule
with config
or processor
as needed.
In terms of actual changes needed for this:
- Mention the new schema in the custom rule documentation
- Update the type in @types/eslint
- Update the type in @typescript-eslint/eslint
- Add any additional information to
meta.replacedBy
in core rules as desired (such as in Docs: Mention Stylistic as the source of replacement rules for all the stylistic rules that got deprecated #18053, Fix: remove custom plugins from replacedBy metadata #13274) - Update ESLint's website generator to take into account the additional information
- Augmenting the rule schema should maintain backwards-compatibility for existing rules. But unofficial tooling and documentation sites using these properties may need to be updated to support the new formats.
- Support additional rule metadata for deprecations bmish/eslint-doc-generator#512
This proposal is inspired by:
- Automate docs with eslint-doc-generator jsx-eslint/eslint-plugin-react#3469 (comment)
- Show if rule is enabled by eslint:recommended on rule page #5774 (comment)
Related:
Participation
- I am willing to submit a pull request for this change.
Additional comments
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status