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: Parse error when using FlatCompat in new flat config #17953

Closed
1 task
thepassle opened this issue Jan 4, 2024 · 4 comments
Closed
1 task

Bug: Parse error when using FlatCompat in new flat config #17953

thepassle opened this issue Jan 4, 2024 · 4 comments
Labels
3rd party plugin This is an issue related to a 3rd party plugin, config, or parser bug ESLint is working incorrectly repro:needed

Comments

@thepassle
Copy link

Environment

Node version: 18.19.0
npm version: 9.5.1
Local ESLint version: 8.56.0
Global ESLint version: n/a
Operating System: macos

What parser are you using?

Default (Espree)

What did you do?

Configuration
import * as url from 'url';
import { FlatCompat } from "@eslint/eslintrc";
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
const flatCompat = new FlatCompat({
  baseDirectory: __dirname,
});

import airbnb from 'eslint-config-airbnb-base';

export default [
  ...flatCompat.config(airbnb),
];
import foo from './foo.js';

console.log(foo);

What did you expect to happen?

eslint-config-airbnb-base internally uses eslint-plugin-import. When using the FlatCompat utility to use eslint-config-airbnb-base in my new flat config format, I'm getting the following error, which I'm not getting with the old eslint configuration format:

  1:17  error    Parse errors in imported module './foo.js': parserPath or languageOptions.parser is required! (undefined:undefined)  import/no-named-as-default

I found this confusing, because it does work in the old config format. But it seems like with the new config format, each config object that you export in the array thats exported in eslint.config.js, requires their own parserPath or languageOptions.parser, is that assumption correct? Previously we configured the parser in one place, and when extending that, it applied to everything else. (as far as my understanding goes)

I tried to look into the code a little bit to see whats happening, and it seems like the FlatCompat utility creates the following object for eslint-plugin-import specifically:

{
    settings: {
      'import/resolver': [Object],
      'import/extensions': [Array],
      'import/core-modules': [],
      'import/ignore': [Array]
    },
    rules: {
      'import/no-unresolved': [Array],
      'import/named': 'error',
      'import/default': 'off',
      'import/namespace': 'off',
      'import/export': 'error',
      'import/no-named-as-default': 'error',
      'import/no-named-as-default-member': 'error',
      'import/no-deprecated': 'off',
      'import/no-extraneous-dependencies': [Array],
      'import/no-mutable-exports': 'error',
      'import/no-commonjs': 'off',
      'import/no-amd': 'error',
      'import/no-nodejs-modules': 'off',
      'import/first': 'error',
      'import/imports-first': 'off',
      'import/no-duplicates': 'error',
      'import/no-namespace': 'off',
      'import/extensions': [Array],
      'import/order': [Array],
      'import/newline-after-import': 'error',
      'import/prefer-default-export': 'error',
      'import/no-restricted-paths': 'off',
      'import/max-dependencies': [Array],
      'import/no-absolute-path': 'error',
      'import/no-dynamic-require': 'error',
      'import/no-internal-modules': [Array],
      'import/unambiguous': 'off',
      'import/no-webpack-loader-syntax': 'error',
      'import/no-unassigned-import': 'off',
      'import/no-named-default': 'error',
      'import/no-anonymous-default-export': [Array],
      'import/exports-last': 'off',
      'import/group-exports': 'off',
      'import/no-default-export': 'off',
      'import/no-named-export': 'off',
      'import/no-self-import': 'error',
      'import/no-cycle': [Array],
      'import/no-useless-path-segments': [Array],
      'import/dynamic-import-chunkname': [Array],
      'import/no-relative-parent-imports': 'off',
      'import/no-unused-modules': [Array],
      'import/no-import-module-exports': [Array],
      'import/no-relative-packages': 'error'
    },
    languageOptions: { ecmaVersion: 6, sourceType: 'module' },
    plugins: { import: [Object] }
  },

Note that there's no parserPath or languageOptions.parser present. There is a languageOptions.parser present in other objects of the config, however, but as mentioned above, it seems like that's not getting applied to other objects in the exported flat config array.

When I looked into the code, I saw that the error is thrown in eslint-module-utils:
image

And in the getParserPath I see the following:
image

Judging on the comment, it seems like it should have defaulted to eslints parser, but that is undefined:
image

I'm not too familiar with ESLint's internals, but this feels like it could potentially be a bug, so I figured I'd report it.

So two main questions are:

  • Is my assumption that parser options are not "inherited" anymore, like was the case in the old config format, and instead now every object in the exported flat config array from eslint.config.js needs to configure their own parser options?
  • Is this a bug in ESLint? Or should I report this elsewhere? (like eslint-plugin-import?)

What actually happened?

See explanation above

Link to Minimal Reproducible Example

https://stackblitz.com/edit/stackblitz-starters-g64xvt?file=eslint.config.js

Participation

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

Additional comments

Open the stackblitz and run npm run lint in the terminal to see the result:

  1:17  error    Parse errors in imported module './foo.js': parserPath or languageOptions.parser is required! (undefined:undefined)  import/no-named-as-default
@thepassle thepassle added bug ESLint is working incorrectly repro:needed labels Jan 4, 2024
@aladdin-add
Copy link
Member

it's not eslint's bug - the plugin just has not supported flat configs: import-js/eslint-plugin-import#2943, import-js/eslint-plugin-import#2873

@aladdin-add aladdin-add added the 3rd party plugin This is an issue related to a 3rd party plugin, config, or parser label Jan 4, 2024
@mdjermanovic
Copy link
Member

  • Is my assumption that parser options are not "inherited" anymore, like was the case in the old config format, and instead now every object in the exported flat config array from eslint.config.js needs to configure their own parser options?

context.languageOptions.parser is always defined. If languageOptions.parser isn't specified in config objects, then it defaults to Espree which is set in the default config, so when the config objects are merged with the default config the resulting config for a file will have Espree in languageOptions.parser.

@thepassle
Copy link
Author

  • Is my assumption that parser options are not "inherited" anymore, like was the case in the old config format, and instead now every object in the exported flat config array from eslint.config.js needs to configure their own parser options?

context.languageOptions.parser is always defined. If languageOptions.parser isn't specified in config objects, then it defaults to Espree which is set in the default config, so when the config objects are merged with the default config the resulting config for a file will have Espree in languageOptions.parser.

Okay thanks, so I also just noticed that eslint-module-utils is actually not an official package, but maintained by the same maintainer as eslint-plugin-import, so it seems that this is just a bug on their side then.

Thank you for confirming :) I'll create an issue at eslint-plugin-import

@G-Rath
Copy link
Contributor

G-Rath commented Apr 19, 2024

@mdjermanovic I've been working on v9 support for eslint-plugin-import and was wondering if you could help clarify something about this for me - a lot of tests are failing due to the error in the original description, seemingly because the parser isn't there.

i.e. if you compare this run using v7 to [this run using v9)[https://github.com/import-js/eslint-plugin-import/actions/runs/8747922114/job/24007140735?pr=2996] - even just glancing through the logs you'll see a lot of parserPath: undefined.

I have a feeling the answer is probably that the defaults you linked to are used for the CLI but not by RuleTester - does that sound right to you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3rd party plugin This is an issue related to a 3rd party plugin, config, or parser bug ESLint is working incorrectly repro:needed
Projects
Archived in project
Development

No branches or pull requests

4 participants