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

Bug: import/no-unused-modules ESLint couldn't find a non-standard name configuration file #16787

Closed
1 task
regseb opened this issue Jan 15, 2023 · 7 comments
Closed
1 task
Labels
3rd party plugin This is an issue related to a 3rd party plugin, config, or parser archived due to age This issue has been archived; please open a new issue for any further discussion

Comments

@regseb
Copy link
Contributor

regseb commented Jan 15, 2023

Environment

Node version: v18.12.1
npm version: 9.2.0
Local ESLint version: 8.32.0
Global ESLint version: N/A
Operating System: Ubuntu 22.04.1 LTS

What parser are you using?

Default (Espree)

What did you do?

package.json:

{
    "name": "testcase",
    "version": "1.0.0",
    "type": "module",
    "private": true,
    "dependencies": {
        "eslint-plugin-import": "2.27.4",
        "eslint": "8.32.0"
    }
}

my_eslint.json:

{
    "plugins": ["import"],
    "parserOptions": {
        "sourceType": "module",
        "ecmaVersion": 2022
    },

    "rules": {
        "import/no-unused-modules": [2, { "unusedExports": true }]
    }
}

index.js:

console.log("foo");

Run this command: npx eslint -c my_eslint.json --debug index.js

If I rename the configuration file to .eslintrc.json, there is no more problem. The error occurs when using a non-standard ESLint configuration file name (different from .eslintrc.*).

What did you expect to happen?

No error reported.

What actually happened?

  eslint:cli CLI args: [ '-c', 'my_eslint.json', '--debug', 'index.js' ] +0ms
  eslint:cli Using flat config? false +4ms
  eslint:cli Running on files +3ms
  eslintrc:config-array-factory Loading JSON config file: /home/regseb/testcase/package.json +0ms
  eslintrc:config-array-factory Loading JSON config file: /home/regseb/testcase/my_eslint.json +0ms
  eslintrc:config-array-factory Loading plugin "import" from /home/regseb/testcase/my_eslint.json +1ms
  eslintrc:config-array-factory Loaded: eslint-plugin-import@2.27.4 (/home/regseb/testcase/node_modules/eslint-plugin-import/lib/index.js) +0ms
  eslintrc:config-array-factory Plugin /home/regseb/testcase/node_modules/eslint-plugin-import/lib/index.js loaded in: 71ms +71ms
  eslintrc:ignore-pattern Create with: [ IgnorePattern { patterns: [ '/**/node_modules/*' ], basePath: '/home/regseb/testcase', loose: false } ] +0ms
  eslintrc:ignore-pattern   processed: { basePath: '/home/regseb/testcase', patterns: [ '/**/node_modules/*' ] } +1ms
  eslintrc:ignore-pattern Create with: [ IgnorePattern { patterns: [ '/**/node_modules/*' ], basePath: '/home/regseb/testcase', loose: false } ] +1ms
  eslintrc:ignore-pattern   processed: { basePath: '/home/regseb/testcase', patterns: [ '/**/node_modules/*' ] } +0ms
  eslint:file-enumerator Start to iterate files: [ 'index.js' ] +0ms
  eslint:file-enumerator File: /home/regseb/testcase/index.js +0ms
  eslintrc:cascading-config-array-factory Load config files for /home/regseb/testcase. +0ms
  eslintrc:cascading-config-array-factory No cache found: /home/regseb/testcase. +0ms
  eslintrc:config-array-factory Loading package.json config file: /home/regseb/testcase/package.json +5ms
  eslintrc:config-array-factory Loading JSON config file: /home/regseb/testcase/package.json +0ms
  eslintrc:config-array-factory Error reading package.json file: /home/regseb/testcase/package.json +0ms
  eslintrc:config-array-factory Config file not found on /home/regseb/testcase +0ms
  eslintrc:cascading-config-array-factory No cache found: /home/regseb. +1ms
  eslintrc:cascading-config-array-factory Stop traversing because of considered root. +0ms
  eslintrc:cascading-config-array-factory Configuration was determined: ConfigArray(2) [ { type: 'config', name: 'DefaultIgnorePattern', filePath: '', criteria: null, env: undefined, globals: undefined, ignorePattern: IgnorePattern { patterns: [Array], basePath: '/home/regseb/testcase', loose: false }, noInlineConfig: undefined, parser: undefined, parserOptions: undefined, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: undefined, settings: undefined }, { type: 'config', name: '--config', filePath: '/home/regseb/testcase/my_eslint.json', criteria: null, env: undefined, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: { sourceType: 'module', ecmaVersion: 2022 }, plugins: { import: [Object] }, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: { 'import/no-unused-modules': [Array] }, settings: undefined } ] on /home/regseb/testcase +3ms
  eslintrc:ignore-pattern Create with: [ IgnorePattern { patterns: [ '/**/node_modules/*' ], basePath: '/home/regseb/testcase', loose: false } ] +6ms
  eslintrc:ignore-pattern   processed: { basePath: '/home/regseb/testcase', patterns: [ '/**/node_modules/*' ] } +0ms
  eslintrc:ignore-pattern Check {
  filePath: '/home/regseb/testcase/index.js',
  dot: false,
  relativePath: 'index.js',
  result: false
} +1ms
  eslint:cli-engine Lint /home/regseb/testcase/index.js +0ms
  eslint:linter Linting code for /home/regseb/testcase/index.js (pass 1) +0ms
  eslint:linter Verify +0ms
  eslint:linter With ConfigArray: /home/regseb/testcase/index.js +0ms
  eslint:linter Parsing: /home/regseb/testcase/index.js +1ms
  eslint:linter Parsing successful: /home/regseb/testcase/index.js +5ms
  eslint:linter Scope analysis: /home/regseb/testcase/index.js +0ms
  eslint:linter Scope analysis successful: /home/regseb/testcase/index.js +1ms
  eslintrc:config-array-factory Loading JSON config file: /home/regseb/testcase/package.json +14ms
  eslintrc:ignore-pattern Create with: [ IgnorePattern { patterns: [ '/**/node_modules/*' ], basePath: '/home/regseb/testcase', loose: false } ] +9ms
  eslintrc:ignore-pattern   processed: { basePath: '/home/regseb/testcase', patterns: [ '/**/node_modules/*' ] } +0ms
  eslint:file-enumerator Start to iterate files: [ '/home/regseb/testcase' ] +15ms
  eslint:file-enumerator Directory: /home/regseb/testcase +0ms
  eslint:file-enumerator Enter the directory: /home/regseb/testcase +0ms
  eslintrc:cascading-config-array-factory Load config files for /home/regseb/testcase. +12ms
  eslintrc:cascading-config-array-factory No cache found: /home/regseb/testcase. +0ms
  eslintrc:config-array-factory Loading package.json config file: /home/regseb/testcase/package.json +1ms
  eslintrc:config-array-factory Loading JSON config file: /home/regseb/testcase/package.json +0ms
  eslintrc:config-array-factory Error reading package.json file: /home/regseb/testcase/package.json +0ms
  eslintrc:config-array-factory Config file not found on /home/regseb/testcase +0ms
  eslintrc:cascading-config-array-factory No cache found: /home/regseb. +0ms
  eslintrc:cascading-config-array-factory Stop traversing because of considered root. +0ms
  eslintrc:cascading-config-array-factory Loading the config file of the home directory: /home/regseb +0ms
  eslintrc:config-array-factory Config file not found on /home/regseb +0ms
  eslintrc:cascading-config-array-factory Configuration was determined: ConfigArray(1) [ { type: 'config', name: 'DefaultIgnorePattern', filePath: '', criteria: null, env: undefined, globals: undefined, ignorePattern: IgnorePattern { patterns: [Array], basePath: '/home/regseb/testcase', loose: false }, noInlineConfig: undefined, parser: undefined, parserOptions: undefined, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: undefined, settings: undefined } ] on /home/regseb/testcase +0ms
  eslintrc:ignore-pattern Create with: [ IgnorePattern { patterns: [ '/**/node_modules/*' ], basePath: '/home/regseb/testcase', loose: false } ] +1ms
  eslintrc:ignore-pattern   processed: { basePath: '/home/regseb/testcase', patterns: [ '/**/node_modules/*' ] } +1ms
  eslintrc:ignore-pattern Check {
  filePath: '/home/regseb/testcase/index.js',
  dot: false,
  relativePath: 'index.js',
  result: false
} +0ms
  eslint:file-enumerator Yield: index.js +2ms
  eslintrc:cascading-config-array-factory Load config files for /home/regseb/testcase. +1ms
  eslintrc:cascading-config-array-factory Cache hit: /home/regseb/testcase. +0ms
  eslint:linter An error occurred while traversing +4ms
  eslint:linter Filename: /home/regseb/testcase/index.js +0ms
  eslint:linter Parser Options: {
  sourceType: 'module',
  ecmaVersion: 13,
  ecmaFeatures: { globalReturn: false }
} +0ms
  eslint:linter Parser Path: espree +0ms
  eslint:linter Settings: {} +0ms

Oops! Something went wrong! :(

ESLint: 8.32.0

ESLint couldn't find a configuration file. To set up a configuration file for this project, please run:

    npm init @eslint/config

ESLint looked for configuration files in /home/regseb/testcase and its ancestors. If it found none, it then looked in your home directory.

If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://eslint.org/chat/help

Participation

  • I am willing to submit a pull request for this issue.

Additional comments

@regseb regseb added bug ESLint is working incorrectly repro:needed labels Jan 15, 2023
@mdjermanovic mdjermanovic added 3rd party plugin This is an issue related to a 3rd party plugin, config, or parser and removed bug ESLint is working incorrectly repro:needed labels Jan 15, 2023
@mdjermanovic
Copy link
Member

Hi @regseb, thanks for the issue!

The import/no-unused-modules rule indirectly loads eslint configs by using eslint's internal module FileEnumerator. This module isn't intended to be used outside eslint package. When used by eslint, FileEnumerator receives full execution context that includes processed CLI options. The error you're getting is caused by the rule not providing the context to the FileEnumerator instance it's using, so it works as if -c my_eslint.json is not specified and therefore looks for .eslintrc.* config files. We can discuss in #13481 how this rule could work with the new config system (cc @ljharb), but until then it seems incompatible with the -c usage.

@ljharb
Copy link
Sponsor Contributor

ljharb commented Jan 15, 2023

Ah, thanks for clarifying.

@ljharb
Copy link
Sponsor Contributor

ljharb commented Jan 15, 2023

@mdjermanovic does that mean if we passed the context to the FileEnumerator instance, it would Just Work with the legacy config system?

@mdjermanovic
Copy link
Member

It might work, but I don't think that rules have access to all the data that ESLint passes to FileEnumerator.

const configArrayFactory = new CascadingConfigArrayFactory({
additionalPluginPool,
baseConfig: options.baseConfig || null,
cliConfig: createConfigDataFromOptions(options),
cwd: options.cwd,
ignorePath: options.ignorePath,
resolvePluginsRelativeTo: options.resolvePluginsRelativeTo,
rulePaths: options.rulePaths,
specificConfigPath: options.configFile,
useEslintrc: options.useEslintrc,
builtInRules,
loadRules,
getEslintRecommendedConfig: () => require("../../conf/eslint-recommended.js"),
getEslintAllConfig: () => require("../../conf/eslint-all.js")
});
const fileEnumerator = new FileEnumerator({
configArrayFactory,
cwd: options.cwd,
extensions: options.extensions,
globInputPaths: options.globInputPaths,
errorOnUnmatchedPattern: options.errorOnUnmatchedPattern,
ignore: options.ignore
});

@ljharb
Copy link
Sponsor Contributor

ljharb commented Jan 15, 2023

ah, and that's not something eslint exposes to rules?

@mdjermanovic
Copy link
Member

No, and FileEnumerator was not intended to be used by rules or in any way other than internally by other ESLint modules. I think the best course of action would be to open an issue describing what this rule needs from ESLint and how that could be implemented in the new config system.

@ljharb
Copy link
Sponsor Contributor

ljharb commented Jan 16, 2023

I'll try to find time to do that. Unfortunately, that won't address issues with existing users, and I'm highly disinclined to make a breaking change.

@eslint-github-bot eslint-github-bot bot locked and limited conversation to collaborators Jul 15, 2023
@eslint-github-bot eslint-github-bot bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Jul 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
3rd party plugin This is an issue related to a 3rd party plugin, config, or parser archived due to age This issue has been archived; please open a new issue for any further discussion
Projects
Archived in project
Development

No branches or pull requests

3 participants