jsx-eslint/eslint-plugin-react

[Bug]: The latest version is giving a ESLint error (No default export found in imported module)

Opened this issue · 7 comments

Is there an existing issue for this?

  • I have searched the existing issues and my issue is unique
  • My issue appears in the command-line and not only in the text editor

Description Overview

Hi team!

First, thanks a lot for the hard work on this library.

The latest version of eslint-plugin-react includes the types for the project, but unfortunately, the types seem to be incorrect.

We're using the plugin eslint-plugin-import-x, which we're also using to validate our ESLint configuration, and this plugin is giving us the following error:

ESLint: No default export found in imported module "eslint-plugin-react". (import-x/default)

The complete output:

❯ pnpm eslint --cache .

/src/react.js
   3:8  error    No default export found in imported module "eslint-plugin-react"  import-x/default

✖ 1 problems (1 error)

The error occurs on the following line:

import react from "eslint-plugin-react";

I then tried to use a named export instead of the default export, as the ESLint rule suggests, but this doesn't seem to work as I'm getting the following error:

SyntaxError: Named export 'configs' not found. The requested module 'eslint-plugin-react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

The JavaScript is using a module.exports statement, as shown here:

https://github.com/jsx-eslint/eslint-plugin-react/blob/master/index.js#L109

However, the index.d.ts exports a single configs namespace that doesn't reflect the code specified in the index.js-file. You can see this by inspecting the index.d.ts file on npmjs.com

https://www.npmjs.com/package/eslint-plugin-react?activeTab=code

Expected Behavior

I'd expect that the TypeScript types reflect the module.exports statement of the index.js file 1:1

eslint-plugin-react version

v7.37.1

eslint version

v9.11.1

node version

v20.17.0

I kind of object to the phrasing of this issue title.

It does not cause an ESLint error. It fails the default rule from eslint-plugin-import-x (which coincidentally is a fork of eslint-plugin-import which @ljharb maintain)

So anyone that doesn't use that rule is not affected, right? That limits the scope and urgency a lot

From the description of the import-x/default rule (same for import/default):

This rule currently does not interpret module.exports = ... as a default export, either, so such a situation will be reported in the importing module.

Not sure why it got triggered now and didn't trigger before though. The types are generated by TypeScript and I see no issues when consuming it through TypeScript, so this seems like an incorrect error?

Or are you having actual issues with the types?

Inspecting the types now, its partly right:

For some reason only this line is generated and exported:

plugin.configs.flat = {

Not everything from

const plugin = {

Replacing the index.js with something like this makes the types generated be more proper:

module.exports = Object.assign(plugin, {
  configs: Object.assign(plugin.configs, {
    flat,
  }),
});

I'm not able to spend more time on this right now though. I have to focus fully on a freelance project.

An alternative strategy could be to just not publish the exact details on any of the types and simply publish a type like what eslint-plugin-unicorn does:

import type {ESLint, Linter} from 'eslint';

declare const eslintPluginUnicorn: ESLint.Plugin & {
	configs: {
		recommended: Linter.Config;
		all: Linter.Config;
		'flat/all': Linter.FlatConfig;
		'flat/recommended': Linter.FlatConfig;
	};
};

export = eslintPluginUnicorn;

@ljharb I would be okay with either solution. Thinking about it some more the unicorn one might be a better one for this package, as it supports such a wide versions of eslint, typescript and node – and publishing every little detail in the types can make it fail on some specific combination of those – especially when one considers all the different ways its possible to configure typescript and how that makes type be interpret differently.

Maintaining and testing ten lines of code is easier than an autogenerated type setup by an outdated typescript.

But now you know the autogenerated one is an alternative and the benefit of the source maps with that approach at least 🙈

#3838 might be related/duplicate

It'd be great if someone could take a look at the types that https://github.com/jsx-eslint/eslint-plugin-react/tree/types generates (you'll have to clone it) and confirm if that solves the issues discussed here.