eslint-plugin-import icon indicating copy to clipboard operation
eslint-plugin-import copied to clipboard

[import/no-unused-modules] - "No files matching the pattern" error

Open EvgenyOrekhov opened this issue 5 years ago • 39 comments

I'm using both eslint-plugin-import and eslint-plugin-json. When there are only *.json files in my project, I get "No files matching the pattern" error from the import/no-unused-modules rule, and ESLint crashes.

Steps to reproduce:

  1. Clone this minimal reproducible case: https://github.com/EvgenyOrekhov/eslint-config-hardcore/tree/no-files-matching-the-pattern-bug
  2. npm install
  3. npm test

Actual result:

> [email protected] test C:\eslint-config-hardcore
> eslint --ext .js,.json .


Oops! Something went wrong! :(

ESLint: 6.8.0.

No files matching the pattern "C:\eslint-config-hardcore" were found.
Please check for typing mistakes in the pattern.

npm ERR! Test failed.  See above for more details.

Expected result: there should be no "No files matching the pattern" error, there should be only one warning from eslint-plugin-json

> [email protected] test C:\eslint-config-hardcore
> eslint --ext .js,.json .


C:\eslint-config-hardcore\invalid.json
  1:2  error  Expected a JSON object, array or literal  json/*

✖ 1 problem (1 error, 0 warnings)

npm ERR! Test failed.  See above for more details.

When I remove the import/no-unused-modules rule from .eslintrc.json, the problem goes away.

EvgenyOrekhov avatar Feb 05 '20 11:02 EvgenyOrekhov

Note that it's not about *.json files. It's about the absence of *.js files. If I try to use the import/no-unused-modules rule in a TypeScript project, and if there are no *.js files, I get the same error.

EvgenyOrekhov avatar Feb 05 '20 11:02 EvgenyOrekhov

This is an error coming from eslint itself. By default, if you're linting "no javascript files", it's probably a bug.

If you have no .foo files, don't pass .foo to --ext.

ljharb avatar Feb 05 '20 18:02 ljharb

@ljharb I have a config that has ~500 rules from 15 different plugins, and only import/no-unused-modules is causing this error.

EvgenyOrekhov avatar Feb 05 '20 21:02 EvgenyOrekhov

Indeed; it's the only rule where we're using eslint's FileEnumerator logic (which is what the command-line eslint uses as well).

You can fix it by configuring here src to be an empty array (it defaults to process.cwd()).

ljharb avatar Feb 05 '20 21:02 ljharb

@ljharb Will it actually perform the analysis this way? Reading the docs makes me think it won't.

EvgenyOrekhov avatar Feb 05 '20 21:02 EvgenyOrekhov

If you have no .js files, then there's nothing to analyze - json files don't import anything. If you have .ts files, then configure src to be ['**/*.ts'].

ljharb avatar Feb 05 '20 23:02 ljharb

@ljharb I would like to be able to use my config in any project, irregardless of which types of files they have, without having to readjust the import/no-unused-modules rule for each one. Is it possible somehow?

EvgenyOrekhov avatar Feb 06 '20 07:02 EvgenyOrekhov

I'm not sure how; many rules - including that one - require per-project config, and env settings are always app-specific.

ljharb avatar Feb 06 '20 08:02 ljharb

@ljharb

If you have no .foo files, don't pass .foo to --ext.

I just tried running eslint --ext .json . on my example, still got the "No files matching the pattern" error.

EvgenyOrekhov avatar Feb 10 '20 10:02 EvgenyOrekhov

I see what you're saying; but the assumption is that an eslint config is always running on the full set of files that config applies to.

One thing you could do is configure using overrides a no-unused-modules rule for each file extension. Does that work?

ljharb avatar Mar 04 '20 05:03 ljharb

@ljharb Tried this:

test.ts

export default 123;

.eslintrc.json

{
    "parserOptions": {
        "ecmaVersion": 2020,
        "sourceType": "module"
    },

    "plugins": ["import"],

    "overrides": [
        {
            "files": ["*.ts"],
            "rules": {
                "import/no-unused-modules": [
                    "error",
                    {
                        "missingExports": false,
                        "unusedExports": true
                    }
                ]
            }
        }
    ]
}
> eslint --ext .ts .


Oops! Something went wrong! :(

ESLint: 6.8.0.

No files matching the pattern "C:\eslint-config-hardcore" were found.
Please check for typing mistakes in the pattern.

npm ERR! Test failed.  See above for more details.

EvgenyOrekhov avatar Mar 05 '20 13:03 EvgenyOrekhov

src isn't configured in that example for the import/no-unused-modules rule; could you configure it?

ljharb avatar Mar 05 '20 21:03 ljharb

@ljharb Yeah, adding "src": ["**/*.ts"], fixed the error.

So, in order to have a generic config that would work with several file extensions without throwing any errors, I would have to do this:

{
    "parserOptions": {
        "ecmaVersion": 2020,
        "sourceType": "module"
    },

    "plugins": ["import"],

    "overrides": [
        {
            "files": ["*.js"],
            "rules": {
                "import/no-unused-modules": [
                    "error",
                    {
                        "src": ["**/*.js"],
                        "missingExports": false,
                        "unusedExports": true
                    }
                ]
            }
        },
        {
            "files": ["*.ts"],
            "rules": {
                "import/no-unused-modules": [
                    "error",
                    {
                        "src": ["**/*.ts"],
                        "missingExports": false,
                        "unusedExports": true
                    }
                ]
            }
        },
        {
            "files": ["*.jsx"],
            "rules": {
                "import/no-unused-modules": [
                    "error",
                    {
                        "src": ["**/*.jsx"],
                        "missingExports": false,
                        "unusedExports": true
                    }
                ]
            }
        },
        {
            "files": ["*.tsx"],
            "rules": {
                "import/no-unused-modules": [
                    "error",
                    {
                        "src": ["**/*.tsx"],
                        "missingExports": false,
                        "unusedExports": true
                    }
                ]
            }
        }
    ]
}

I guess I could live with that, but I would rather prefer to not have to do it.

EvgenyOrekhov avatar Mar 06 '20 15:03 EvgenyOrekhov

Yes, that seems right to me.

One last try for a single config - what if you do "src": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]?

ljharb avatar Mar 06 '20 19:03 ljharb

@ljharb Tried doing that, plus the same extensions in the 'files' array - got the error.

EvgenyOrekhov avatar Mar 06 '20 20:03 EvgenyOrekhov

In that case I think the multiple configs is the only current option.

It seems useful to preserve the error if any of the globs you provide result in matching zero files.

ljharb avatar Mar 06 '20 21:03 ljharb

If I had to do it for every rule, that would be horrible.

EvgenyOrekhov avatar Mar 07 '20 06:03 EvgenyOrekhov

Very true, but most rules apply to a file; this one has to check a whole codebase.

ljharb avatar Mar 07 '20 06:03 ljharb

@ljharb Trying to fix it here: https://github.com/EvgenyOrekhov/eslint-config-hardcore/pull/59/files. Something weird is going on, now I'm getting a false positive: https://travis-ci.org/EvgenyOrekhov/eslint-config-hardcore/builds/659511799#L213. Am I missing something?

EvgenyOrekhov avatar Mar 07 '20 12:03 EvgenyOrekhov

Hmm, i wonder if with this approach, TS files not used by TS files (etc) would be considered unused.

In other words, I’m no longer sure if it’s possible for this rule to support the use case of running on “not every extension the codebase uses at once”. In other words, this might after all require each project to configure it themselves (ie, it might not be possible to configure it in a generic sense, for a shared config)

ljharb avatar Mar 07 '20 17:03 ljharb

I know that in ESLint 7 they will have some changes to the way ESLint handles file extensions. For example, they will not require using the --ext option, having overrides with specific extensions will be enough. Maybe it will fix this issue with no-unused-modules.

EvgenyOrekhov avatar Mar 07 '20 22:03 EvgenyOrekhov

@ljharb I upgraded ESLint to 7.0.0 and removed the --ext option in my examples (the minimal reproducible case and the workaround), and I'm still getting the same errors.

EvgenyOrekhov avatar May 09 '20 11:05 EvgenyOrekhov

@EvgenyOrekhov when i clone your minimal repro, and run npm install, npm test passes (as does npx eslint . and npx eslint --ext=.json *.json). What should I see?

ljharb avatar Jun 01 '20 17:06 ljharb

@ljharb Make sure you checkout the no-files-matching-the-pattern-bug branch after you clone the repo. I get No files matching the pattern "C:\eslint-config-hardcore" were found. error.

I updated the code to use eslint . command. The goal is to make eslint . command (without any extra options like --ext) work even when there are no *.js files in the folder.

EvgenyOrekhov avatar Jun 01 '20 18:06 EvgenyOrekhov

@ljharb I added a Travis CI config, you can see the log here: https://travis-ci.com/github/EvgenyOrekhov/eslint-config-hardcore/builds/169082082.

EvgenyOrekhov avatar Jun 01 '20 18:06 EvgenyOrekhov

aha, the branch :-) thanks, will look.

ljharb avatar Jun 01 '20 18:06 ljharb

@EvgenyOrekhov sooooo yay? I reproduced your error, and then i npm linked in the master branch of eslint-plugin-import, and now I get:

/path/to/eslint-config-hardcore/invalid.json
  1:2  error  Expected a JSON object, array or literal  json/*

✖ 1 problem (1 error, 0 warnings)

Looks like the next release will fix this?

ljharb avatar Jun 01 '20 18:06 ljharb

@ljharb Great, looks like it will! Feel free to close this issue. I will check it once the next version is released.

EvgenyOrekhov avatar Jun 01 '20 19:06 EvgenyOrekhov

Thanks for the repro case :-) if there's a trivial way to add it as a test case to this repo, so we don't regress, that would be awesome too.

ljharb avatar Jun 01 '20 20:06 ljharb

Hmm; I just tried again and the error occurs again, even with it linked - but when I try to make a test case in this repo, it provides the expected error.

I wonder if merely updating your lockfile with npm update would fix it - could you confirm?

ljharb avatar Jun 05 '20 21:06 ljharb