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

Support eslint flat config

Open silverwind opened this issue 2 years ago • 27 comments

Likely depends on https://github.com/import-js/eslint-plugin-import/issues/2556 but it's good to track nonetheless.

Ref: https://github.com/eslint/eslint/issues/18093

silverwind avatar Mar 09 '24 15:03 silverwind

eslint-plugin-i is now eslint-plugin-import-x.

I'm focusing on TypeScript migration first, see also #41.

After that, I'll start working on new features like supporting flat config.

JounQin avatar Mar 13 '24 11:03 JounQin

Just to mention, some rules will break when using flat config. See this comment

In brief, eslint will fail to use eslint.config.js as config file after enabling import/no-unused-modules with unusedExports: true

Related issues:

  • https://github.com/eslint/eslint/issues/16485
  • https://github.com/import-js/eslint-plugin-import/issues/2907
  • https://github.com/import-js/eslint-plugin-import/issues/2964

meteorlxy avatar Mar 18 '24 14:03 meteorlxy

Interesting, we are using eslint-plugin-import-x now with the Flat Config:

  • https://github.com/import-js/eslint-plugin-import/issues/2948#issuecomment-2119214365

This seems to be working for us so far:

Simplified version of the code:

import eslintImportX from 'eslint-plugin-import-x';

/** @type {import('@typescript-eslint/utils/ts-eslint').FlatConfig.ConfigArray} */
const configArray = [
  {
    plugins: {
     'import-x': eslintImportX,
    },
    settings: {
      'import-x/parsers': {
        '@typescript-eslint/parser': ['.ts', '.tsx'],
      },
      'import-x/resolver': {
        // Load <rootdir>/tsconfig.json
        typescript: true,
        node: true,
      },
    },
    rules: {
      // Error on imports that don't match the underlying file system
      // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-unresolved.md
      'import-x/no-unresolved': 'error',
  },
];

karlhorky avatar May 19 '24 12:05 karlhorky

@karlhorky I am trying out this plugin with the flat config. I copy pasted the config from your post, but I get these errors:

image

(I enabled more rules than simply import-x/no-unresolved.)

Any idea on how to fix?

Zamiell avatar May 30 '24 23:05 Zamiell

module.exports = {
    extends: [
        'plugin:import-x/recommended',
        'plugin:import-x/typescript',
    ],
}

can only be translate into

export default [
    ...compat.config(pluginImportX.configs.recommended), // https://github.com/un-ts/eslint-plugin-import-x/issues/29#issuecomment-2148843214
    pluginImportX.configs.typescript, // no need of wrapping in compat.config() since there's no pluginImportX.configs.typescript.plugins
];

since https://github.com/un-ts/eslint-plugin-import-x/blob/3abe5e49683e0f973232bb631814b935e1ca7091/src/config/recommended.ts#L7 is still passing string as plugin.

n0099 avatar Jun 05 '24 04:06 n0099

@n0099 where is compat coming from?

Is there an example of a simple flat config for eslint v9 that uses this plugin?

My super simple set up works for everything but the import sorting.

import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginImportX from "eslint-plugin-import-x";

export default [
  {
    languageOptions: { globals: globals.browser },
    ignores: ["./dist/"],
  },
  pluginJs.configs.recommended,
  ...tseslint.configs.recommended,
  pluginImportX.configs.typescript,
];

onx2 avatar Jun 08 '24 20:06 onx2

@n0099 where is compat coming from?

@eslint/eslintrc https://github.com/ota-meshi/typescript-eslint-parser-for-extra-files/issues/95#issuecomment-2148604881

import { FlatCompat } from '@eslint/eslintrc';

My super simple set up works for everything but the import sorting.

If you only want to extends from typescript rules, the plugin is not defined in the rule: https://github.com/un-ts/eslint-plugin-import-x/blob/3abe5e49683e0f973232bb631814b935e1ca7091/src/config/typescript.ts#L16-L35 so manually add plugin define to let eslint know where to find define for rules with prefix import-x/

+  { plugins: { 'import-x': pluginImportX } },
  pluginImportX.configs.typescript,

or just also extending recommended rules:

+  ...compat.config(pluginImportX.configs.recommended),
  pluginImportX.configs.typescript,

n0099 avatar Jun 08 '24 23:06 n0099

Where do you import compat from?

muuvmuuv avatar Jun 24 '24 08:06 muuvmuuv

Where do you import compat from?

https://github.com/un-ts/eslint-plugin-import-x/issues/29#issuecomment-2156223337

GalindoSVQ avatar Jun 24 '24 08:06 GalindoSVQ

Just to mention, some rules will break when using flat config. See this comment

In brief, eslint will fail to use eslint.config.js as config file after enabling import/no-unused-modules with unusedExports: true

Related issues:

* [Bug: can not find flat file config eslint/eslint#16485](https://github.com/eslint/eslint/issues/16485)

* [import/no-unused-modules breaks `--no-eslintrc` and eslint fails import-js/eslint-plugin-import#2907](https://github.com/import-js/eslint-plugin-import/issues/2907)

* [Add note(s) to docs about flat configs and/or no-unused-modules' `unusedExports` not being supported in flat configs import-js/eslint-plugin-import#2964](https://github.com/import-js/eslint-plugin-import/issues/2964)

Also this https://github.com/eslint/eslint/issues/18087

KristjanTammekivi avatar Jul 02 '24 08:07 KristjanTammekivi

Chiming in here to say that I don't think the ecosystem uses import/no-unused-modles anymore in favor of knip. Since ESLint is designed to parse individual files (as the linked GitHub issue above shows), it makes more sense to do this kind of project-level checking in a separate tool.

Are any other rules than import/no-unused-modles broken by the flat config?

Zamiell avatar Jul 02 '24 12:07 Zamiell

Let's deprecate no-unused-modles then~!

SukkaW avatar Jul 07 '24 15:07 SukkaW

@Zamiell The discussion about deprecating no-unused-modules rule can be found here: https://github.com/un-ts/eslint-plugin-import-x/issues/90

SukkaW avatar Jul 08 '24 08:07 SukkaW

Never heard about knip, but I'm generally in favor of at least disabling rules that are duplicate with what typescript already validates, if the linted file is typescript, of course. But I guess this is more of a config topic than a plugin topic.

silverwind avatar Jul 08 '24 16:07 silverwind

It works great in flat config 👍🏻 but no-unused-modules leads to an eslint error that the eslint config is missing.

GerroDen avatar Jul 25 '24 10:07 GerroDen

It works great in flat config 👍🏻 but no-unused-modules leads to an eslint error that the eslint config is missing.

Yes. This is because no-unused-modules uses an ESLint internal private API that was designed to be used for crawling eslintrc files.

Currently, I am working on a more performant no-cycle rule alternative.

@silverwind would you like to replace the FileEnumerator w/ a globbing function?

SukkaW avatar Jul 25 '24 11:07 SukkaW

In https://github.com/import-js/eslint-plugin-import/pull/3018 they used @nodelib/fs.walk to replace it, if I understand correctly. Seems like a popular enough dependency to use.

silverwind avatar Jul 25 '24 11:07 silverwind

Maybe @michaelfaith would be interested in porting their work here in case that PR stalls because of those "node 4 concerns" which we do not have with this fork 😆.

silverwind avatar Jul 25 '24 11:07 silverwind

Maybe @michaelfaith would be interested in porting their work here in case that PR stalls because of those "node 4 concerns" which we do not have with this fork 😆.

Yeah. @michaelfaith if you are interested, you can port that PR to eslint-plugin-import-x as well. We use TypeScript and we are not limited to Node.js 4.

SukkaW avatar Jul 25 '24 11:07 SukkaW

Sure, I don't mind helping out, when I have some time.

michaelfaith avatar Jul 25 '24 18:07 michaelfaith

In https://github.com/import-js/eslint-plugin-import/pull/3018 they used @nodelib/fs.walk to replace it

note the fs.walk approach discussed in https://github.com/import-js/eslint-plugin-import/pull/3018 for replacing FileEnumerator depends on a proposed eslint API that’s currently only hypothetical'

I’d support deprecating no-unused-modules and skipping support for using that rule with flat config

controversial avatar Aug 03 '24 17:08 controversial

that’s currently only hypothetical

Did you mean context.session?

I’d support deprecating no-unused-modules and skipping support for using that rule with flat config

I've considered deprecating no-unused-modules (https://github.com/un-ts/eslint-plugin-import-x/issues/90) but I changed my idea.

And as long as we don't include this rule in the flat config, everything would be fine.

SukkaW avatar Aug 04 '24 09:08 SukkaW

I'd definitely keep it at this point, it's too valuable and not everyone wants to install another dependency and fight its config just to replace one rule.

silverwind avatar Aug 04 '24 09:08 silverwind

Yeah

that’s currently only hypothetical

Did you mean context.session?

Yeah, I wouldn't really say "hypothetical". Proposed is accurate though. The two functions that I used in that implementation were added in a POC branch of the eslint repo to prove the proposed api. The idea is that the code would use those functions if they were on the context, and if not, fall back to the old implementation. And if, between now and when the API is finalized, those functions get introduced with a slightly different shape, then the implementation would need to be adjusted. It'd be the same here, if that's the route you want to go. I did use the POC branch in the eslint repo to work against, though. So it did prove the solution out.

michaelfaith avatar Aug 04 '24 14:08 michaelfaith

Oh, and to add a little more context: that api very likely would have already been added to ESLint in v9, if it weren't for the feet-dragging from the eslint-plugin-import project in validating the approach. If the API is ever going to be added, there needs to be an expressed demand for it. So if you want it, this could be a good way to express that demand. Food for thought.

michaelfaith avatar Aug 04 '24 15:08 michaelfaith

I started a draft PR, with everything except the changes to no-unused-module. I wanted to confirm that that's the direction you want to go before implementing it.

michaelfaith avatar Aug 04 '24 16:08 michaelfaith

that’s currently only hypothetical

Did you mean context.session?

Yes, I’m talking about context.session.isDirectoryIgnored() and context.session.isFileIgnored()! These were proposed by nzakas as a way to enable fs.walk approaches to replicate the functionality of the FileEnumerator API. There’s a POC in a branch of eslint, but hasn’t been merged into eslint proper, as @michaelfaith explained!

controversial avatar Aug 05 '24 16:08 controversial