25

If I add any given ESLint rule, for example no-param-reassign in an existing codebase I'm likely to get many violations.

Is there a good way to programmatically add, on line-by-line bases, suppressions for all existing violations?

In the example case:

// eslint-diable-next-line no-param-reassign
param = foo;

To clarify

I do want the rule in my project, guarding all new code we write. I don't want to fix all the old code that is emitting violations by hand (I want a script to do that for me or eslint itself if possible). This is why I would like to suppress all existing violations but respect all new violations. My main goal is to comply with the new rule as fast as possible to get the value from it on all new code. I don't mind old lingering suppressed violations.

Red Mercury
  • 3,971
  • 1
  • 26
  • 32
  • Turn the rule off? – dwjohnston Mar 11 '20 at 03:53
  • Cool - good clarification. – dwjohnston Mar 11 '20 at 04:15
  • 1
    Well eslint can fix certain things automatically, but not everything - depends on the case. Run it at the command line with the --fix option. (I know that's not what you are asking, but you can at least clean up the auto-fixable ones) – see sharper Mar 11 '20 at 04:35
  • There is an issue https://github.com/eslint/eslint/issues/11948 that suggest using the json formatter – Red Mercury Mar 11 '20 at 10:41
  • Came up again in https://github.com/eslint/eslint/issues/13439 and was rejected as something that shouldn't be added to the core project. Makes sense to use something like https://github.com/facebook/jscodeshift instead. – Turadg Feb 18 '21 at 01:36

7 Answers7

12

I was having this same issue with a bunch of react-hooks/exhaustive-deps lint warnings ended up using the json formatter and a script to insert the eslint disable comment. I ran yarn lint . -f json -o warnings.json to get the json list of lints and then this

const json = require('./warnings.json');
const fs = require('fs');

json.forEach(({ filePath, messages, source }) => {
  // if there is no source we have nothing that needs to be eslint-ignore'd
  if (!source) {
    return;
  }

  const data = source.split('\n');

  // if the source has multiple lines which need to be eslint-ignored our offset changes per addition
  // offset is 1 because line numbers start at 1 but index numbers in an array start at 0
  let offset = 1;

  // group errors/warnings by line because we want to have one eslint disable comment with all the rules to disable
  const groupedMessages = messages.reduce((acc, next) => {
    const prevMessages = acc[next.line] ? acc[next.line] : [];
    // some lines may have the same rule twice
    const duplicateRuleForLine = prevMessages.find(message => message.ruleId === next.ruleId);
    // ignore jsx and graphql lint rules
    const applicableRule = next.ruleId && !next.ruleId.includes('jsx') && !next.ruleId.includes('graphql');

    // ignore the eslint-ignore addition for duplicates and non applicable rules
    if (duplicateRuleForLine || !applicableRule) {
      return acc;
    }

    return {
      ...acc,
      [next.line]: [...prevMessages, next],
    };
  }, {});

  Object.entries(groupedMessages).forEach(([line, messages]) => {
    // grouped ignores
    const ignore = `// eslint-disable-next-line ${messages.map(({ ruleId }) => ruleId).join(' ')}`;
    data.splice(line - offset, 0, ignore);
    offset--;
  });

  const updated = data.join('\n');

  fs.writeFile(filePath, updated, function(err) {
    if (err) return console.log(err);
  });
});

Worked out well for me, although I wish these comments I inserted were auto-formatted.

Jonathan Portorreal
  • 2,730
  • 4
  • 21
  • 38
  • If you use `prettier` in conjunction with `eslint`, you can run another `yarn lint --fix` after this script to format them. Thanks for this. – infinity Mar 30 '21 at 09:26
4

I use this typically: https://github.com/amanda-mitchell/suppress-eslint-errors

Getting jscodemod configured for your repo is a bit tough, but worth it once you get it working. A lot of powerful codemods out there.

4

I tried suppress-eslint-errors npm answered by @user15185791, but it did not work with ESLint8. But, I was able to find https://github.com/mizdra/eslint-interactive from that npm issue. So far this wonderful npm is working perfectly.

The execution is as follows command.

yarn add -D eslint-interactive
yarn eslint-interactive src
yarn remove eslint-interactive
katsusuke
  • 461
  • 4
  • 5
-2

You can remove the particular rule that you don't want in your project by modifying the .eslintrc.* file or an eslintConfig field in a package.json file. As they are responsible for the rules in your project. If you remove any rule from them, your editor will stop looking for that violation.

If you still want those rule for future development then don't modify your rules config file, instead of that there are two things that you can do,

  1. Suppress the old code that is violating the rules.

  2. Fix them. (recommended)

Anurodh Singh
  • 814
  • 5
  • 9
  • Thanks for answering! I do want the rule in my project, guarding all new code we write. I don't want to fix all the old code that is emitting violations. This is why I would like to suppress all existing violations but respect all new violations. I'll edit my question to clarify – Red Mercury Mar 11 '20 at 04:01
  • If you want those rule for future development then there are two things that you can do 1. Suppress the old code that is violating the rules. 2. Fix them. (recommended) – Anurodh Singh Mar 11 '20 at 04:03
  • Yeah I can suppress them all myself but the gist of my question is: Can i avoid that without much hassle? My main goal is to comply with the new rule to get the value from it. I don't mind lingering suppressed violations – Red Mercury Mar 11 '20 at 04:08
-2

For an individual line:

// eslint-disable-next-line

For a block

/* eslint-disable */
// liniting issues here
/* eslint-enable */

Without eslint-disable, linting will be disabled for the rest of the file

Brian Barnes
  • 1,009
  • 7
  • 15
-3

In order to accomplish what you want, you should disable eslint for those old files that you want ESLint to ignore completely. Add this to the top of your old files:

/* eslint-disable */

Here are more ways to accomplish different disabling:

Evgenii Klepilin
  • 695
  • 1
  • 8
  • 21
  • Thanks for responding! I do not want to disable eslint on any wider scope than necessary. I want to catch new violations of any type in any file and on any line. In addition I'd like to avoid doing any of the suppressions manually. I should be something a script can do. And honestly feels like eslint should provide! But I don't think it does ;( I clarified my question to explain the problem better. – Red Mercury Mar 11 '20 at 04:21
-3

If you don’t want to go file by file adding these directives, you could use ESLint overrides feature. In .eslintrc:

{
  /*
    Main set of properties here
    ...
  */
  overrides: [
    {
      files: [
        /*
          List of glob patterns matching files that should have
          some rules overwritten
        */
      ],
      rules: [
        /* 
          Add the common rules here, otherwise they'll be overwritten.
          After that, add the ones you want to disable:
        */
        no-param-reassign: 0,
      ]
    },
  ],
}

Otherwise, if you want to disable a rule in a single line, you just need to do like this:

// eslint-disable-nex-line <rule name>

Finally, if you want to disable a rule in many lines of code, you can use:

// eslint-disable <rule name>

// Code on which the rule shouldn't be applied
// ...

// eslint-enable <rule name>