@morev/eslint-disable-autofix
Version:
Utility to disable autofix for specific ESLint rules
140 lines (106 loc) • 5.42 kB
Markdown
<!-- markdownlint-disable-next-line md033 -->
<img src="./.github/assets/banner.svg" alt="Promo image of @morev/eslint-disable-autofix package" width="830" height="465" />

[](https://opensource.org/licenses/MIT)




# @morev/eslint-disable-autofix
This utility allows you to disable autofix for specific ESLint rules by using a custom prefix in your configurations. \
It's useful when you want a rule to remain active for linting purposes but prevent ESLint from automatically fixing it.
---
> [!NOTE]
> This is a temporary solution until [this RFC](https://github.com/eslint/rfcs/pull/134) is accepted
> and a final implementation is made that closes [this issue](https://github.com/eslint/eslint/issues/18696) -
> after that the feature for disabling autofix for rules will be in the ESLint core.
>
> I am working on RFC development and final implementation in the core myself,
> but the process will take some time, and the problem is already there.
>
> I'll probably be able to implement this as a polyfill for the final solution,
> once [the RFC](https://github.com/eslint/rfcs/pull/134) discussion reaches
> a consensus on a public API.
---
> [!IMPORTANT]
>
> * Only works with ESLint v9 and its flat config format;
> * You have to restart ESLint server after adding/removing `no-autofix/` prefix to take effect.
---
## Why?
Some rules support autofixing, which is often convenient, but in certain cases
the fixes may be broken, unsafe, or simply undesirable. \
Ideally, unsafe autofixes should be treated as suggestions, and broken fixes should be reported.
However, ESLint is a large ecosystem, and some useful plugins are no longer actively maintained. \
Even in actively maintained projects, users may want to disable autofixing for specific rules
due to project-specific or personal preferences.
## Installation
```bash
pnpm add -D @morev/eslint-disable-autofix
```
```bash
yarn add @morev/eslint-disable-autofix -D
```
```bash
npm install -D @morev/eslint-disable-autofix
```
## Usage
### Basic usage
In your `eslint.config.js` (only flat config is supported):
```js
import { disableAutofix } from '@morev/eslint-disable-autofix';
import somePlugin from 'some-eslint-plugin';
export default disableAutofix([
{
plugins: {
'some-plugin': somePlugin,
},
rules: {
// Disable autofix for a core rule
'no-autofix/no-var': 'error',
// Disable autofix for a third-party rule
'no-autofix/some-plugin/some-rule': 'warn',
},
},
]);
```
### Custom prefix
If you'd prefer a custom prefix other than `no-autofix/`, use the factory:
```js
import { createDisableAutofix } from '@morev/eslint-disable-autofix';
const disableAutofix = createDisableAutofix({
prefix: 'disable-autofix',
});
export default disableAutofix([
{
rules: {
'disable-autofix/no-var': 'error',
},
},
]);
```
## How it works internally
1. Scans passed ESLint configurations for rules with a specified prefix;
1. Strips the prefix to keep the original name of the rule;
1. Patches rules from ESLint core or third-party plugins directly to disable autofix.
Under the hood, it uses [`eslint-rule-composer`](https://github.com/not-an-aardvark/eslint-rule-composer)
to wrap rules with autofix disabled.
>[!CAUTION]
> Direct patching is quite risky and hacky, it relies on non-public ESLint API. \
> While it's currently the only way to access certain rule internals,
> it may break in future ESLint versions.
## Alternatives
I've been using [eslint-plugin-no-autofix](https://github.com/aladdin-add/eslint-plugin/tree/master/packages/no-autofix)
for a long time and haven't had much trouble with it, however recently problems have arisen:
1. Some popular plugins (like [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn)
or [eslint-stylistic](https://github.com/eslint-stylistic/eslint-stylistic))
switch to the ESM-only distribution format and
[eslint-plugin-no-autofix](https://github.com/aladdin-add/eslint-plugin/tree/master/packages/no-autofix) doesn't work with it.
The [issue have no response](https://github.com/aladdin-add/eslint-plugin/issues/104),
so I've decided to create my own solution that works in a different way.
1. I'm getting tired of rules being renamed just to make them work. \
Say I need to disable a rule with autofix turned off for a single file - I write `/* eslint-disable no-autofix/unicorn/no-lonely-if */`. \
Later, the broken autofix in the original rule gets fixed, I re-enable the main rule,
and now the directive no longer applies, which leads to unexpected changes I didn't want.
Patching the original rules instead of creating new ones might be a bit riskier technically,
but from a developer experience perspective, it's definitely cleaner and more intuitive.