eslint: CLIEngine#getRules doesn't work before linting files

I’m trying to find a way to dynamically create eslint configs during the execution. The idea is to filter out all auto-fixable rules from all plugins and presets defined in user’s .eslintrc configs for specified environments (local development). The motivation is to leave fixes to https://github.com/okonet/lint-staged and remove unnecessary distractions from code editors. At the same time, on CI these rules must result in error if not followed (users can skip precommit hooks).

I’ve found and tried https://eslint.org/docs/developer-guide/nodejs-api#clienginegetrules already but this gives me same set of rules regardless of my .eslintrc and this set doesn’t take any plugins into account.

The documentation says This method returns a map of all loaded rules. but I’m not sure what loaded means in this context.

  • ESLint Version:

ESLint 4.19.1 and v5.5.0

  • Node Version:

v8 and v10

  • npm Version:

v5

What parser (default, Babel-ESLint, etc.) are you using?

Please show your full configuration:

Configuration
{
  "rules": {
    "no-semi": 2
  }
}

What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.

const CLIEngine = require("eslint").CLIEngine;
const cli = new CLIEngine();

console.log(cli.getRules().keys());
node ./getEslintRules.js
[Map Iterator] {
  'accessor-pairs',
  'array-bracket-newline',
  'array-bracket-spacing',
  'array-callback-return',
  'array-element-newline',
  'arrow-body-style',
  'arrow-parens',
  'arrow-spacing',
  'block-scoped-var',
  'block-spacing',
  'brace-style',
  'callback-return',
  'camelcase',
  'capitalized-comments',
  'class-methods-use-this',
  'comma-dangle',
  'comma-spacing',
  'comma-style',
  'complexity',
  'computed-property-spacing',
  'consistent-return',
  'consistent-this',
  'constructor-super',
  'curly',
  'default-case',
  'dot-location',
  'dot-notation',
  'eol-last',
  'eqeqeq',
  'for-direction',
  'func-call-spacing',
  'func-name-matching',
  'func-names',
  'func-style',
  'function-paren-newline',
  'generator-star-spacing',
  'getter-return',
  'global-require',
  'guard-for-in',
  'handle-callback-err',
  'id-blacklist',
  'id-length',
  'id-match',
  'implicit-arrow-linebreak',
  'indent-legacy',
  'indent',
  'init-declarations',
  'jsx-quotes',
  'key-spacing',
  'keyword-spacing',
  'line-comment-position',
  'linebreak-style',
  'lines-around-comment',
  'lines-around-directive',
  'lines-between-class-members',
  'max-depth',
  'max-len',
  'max-lines',
  'max-nested-callbacks',
  'max-params',
  'max-statements-per-line',
  'max-statements',
  'multiline-comment-style',
  'multiline-ternary',
  'new-cap',
  'new-parens',
  'newline-after-var',
  'newline-before-return',
  'newline-per-chained-call',
  'no-alert',
  'no-array-constructor',
  'no-await-in-loop',
  'no-bitwise',
  'no-buffer-constructor',
  'no-caller',
  'no-case-declarations',
  'no-catch-shadow',
  'no-class-assign',
  'no-compare-neg-zero',
  'no-cond-assign',
  'no-confusing-arrow',
  'no-console',
  'no-const-assign',
  'no-constant-condition',
  'no-continue',
  'no-control-regex',
  'no-debugger',
  'no-delete-var',
  'no-div-regex',
  'no-dupe-args',
  'no-dupe-class-members',
  'no-dupe-keys',
  'no-duplicate-case',
  'no-duplicate-imports',
  'no-else-return',
  'no-empty-character-class',
  'no-empty-function',
  'no-empty-pattern',
  'no-empty',
  'no-eq-null',
  ... 157 more items }

What did you expect to happen?

For this config I expect only no-semi to be in the list of loaded rules.

What actually happened? Please include the actual, raw output from ESLint.

Instead I always (independent of config) get this set or rules:

{
  'accessor-pairs',
  'array-bracket-newline',
  'array-bracket-spacing',
  'array-callback-return',
  'array-element-newline',
  'arrow-body-style',
  'arrow-parens',
  'arrow-spacing',
  'block-scoped-var',
  'block-spacing',
  'brace-style',
  'callback-return',
  'camelcase',
  'capitalized-comments',
  'class-methods-use-this',
  'comma-dangle',
  'comma-spacing',
  'comma-style',
  'complexity',
  'computed-property-spacing',
  'consistent-return',
  'consistent-this',
  'constructor-super',
  'curly',
  'default-case',
  'dot-location',
  'dot-notation',
  'eol-last',
  'eqeqeq',
  'for-direction',
  'func-call-spacing',
  'func-name-matching',
  'func-names',
  'func-style',
  'function-paren-newline',
  'generator-star-spacing',
  'getter-return',
  'global-require',
  'guard-for-in',
  'handle-callback-err',
  'id-blacklist',
  'id-length',
  'id-match',
  'implicit-arrow-linebreak',
  'indent-legacy',
  'indent',
  'init-declarations',
  'jsx-quotes',
  'key-spacing',
  'keyword-spacing',
  'line-comment-position',
  'linebreak-style',
  'lines-around-comment',
  'lines-around-directive',
  'lines-between-class-members',
  'max-depth',
  'max-len',
  'max-lines',
  'max-nested-callbacks',
  'max-params',
  'max-statements-per-line',
  'max-statements',
  'multiline-comment-style',
  'multiline-ternary',
  'new-cap',
  'new-parens',
  'newline-after-var',
  'newline-before-return',
  'newline-per-chained-call',
  'no-alert',
  'no-array-constructor',
  'no-await-in-loop',
  'no-bitwise',
  'no-buffer-constructor',
  'no-caller',
  'no-case-declarations',
  'no-catch-shadow',
  'no-class-assign',
  'no-compare-neg-zero',
  'no-cond-assign',
  'no-confusing-arrow',
  'no-console',
  'no-const-assign',
  'no-constant-condition',
  'no-continue',
  'no-control-regex',
  'no-debugger',
  'no-delete-var',
  'no-div-regex',
  'no-dupe-args',
  'no-dupe-class-members',
  'no-dupe-keys',
  'no-duplicate-case',
  'no-duplicate-imports',
  'no-else-return',
  'no-empty-character-class',
  'no-empty-function',
  'no-empty-pattern',
  'no-empty',
  'no-eq-null',
  ... 157 more items }

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 19 (18 by maintainers)

Commits related to this issue

Most upvoted comments

Working on this if thats alright

The current logic for loading rules is a fairly convoluted. The rules from plugins actually get loaded here during config processing. As you noticed, rules.js -> #load is used to load bundled rules and rules from a folder provided with the --rulesdir flag, but it isn’t used to load rules from plugins.

Currently, CLIEngine loads rules correctly when linting text, since it always processes a config before linting the text, and the rules get added when the config is processed. With getRules, CLIEngine isn’t loading any config, so it never adds the plugin rules, resulting in the buggy behavior described in this issue. So I think the simplest solution for now would be to have CLIEngine compute a config in getRules to ensure that the plugin rules get added (i.e. the first solution you proposed).

Eventually, it would be nice to refactor this so that loading a config doesn’t have confusing side-effects, but I think that’s outside the scope of this issue.