62

After looking at the documentation for the import/no-named-as-default eslint rule, I'm still confused about what exactly I'm doing wrong.

I have the following file structure

.
├── ButtonBack.css
├── ButtonBack.jsx
├── __tests__
│   └── ButtonBack.test.jsx
└── index.js

The ButtonBack.jsx contains the following code

import React from 'react';
import PropTypes from 'prop-types';

export default class ButtonBack extends React.Component {
  ... code removed to keep example short ...
}

__tests__/ButtonBack.test.jsx contains the following code

import React from 'react';
import { shallow } from 'enzyme';
import ButtonBack from '../ButtonBack'; // <== this line has an eslint warning

... code removed to keep example short ...

The problem is, my linter says that import ButtonBack from '../ButtonBack violates the following lint rules:

I can't figure out why my import statement violates the lint rule. Removing the name of the class in ButtonBack.jsx (export default class extends React.Component) does not solve the issue either.

5
  • Are there any other exports in ButtonBack.jsx, or just the export default class ButtonBack?
    – btmills
    Commented Jun 8, 2017 at 14:15
  • Just the one export. Commented Jun 8, 2017 at 15:08
  • did you get to a solution on this or did you just disable the rule?
    – Doug
    Commented Oct 26, 2017 at 17:25
  • I just disabled the rule. 😐 Commented Oct 30, 2017 at 12:07
  • 1
    This ESLint rule is lame
    – duhaime
    Commented Nov 23, 2021 at 23:38

9 Answers 9

65

Ran into this same issue and from what I'm seeing you're going to just have to disable that rule (that's what I did at least)

"Unfortunately, React + Redux is the most common scenario. However, there are lots of other cases where HOCs will force developers to shut down this rule."

https://github.com/benmosher/eslint-plugin-import/issues/544

https://github.com/reactjs/react-redux/issues/119

https://github.com/18F/calc/pull/1235

.eslintrc

"rules": {
    "import/no-named-as-default": 0
}
2
  • Also add "import/no-named-as-default-member": 0, if you're also facing default-member error though it's a default export and not a named export. Commented Apr 12 at 7:52
  • A solution I've just found is that we can keep this rule but we can shut down this rule for the libraries that are imported from node_modules folder. In your eslint config file, override this rule for node_modules lang-js "overrides": [ { "files": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"], "excludedFiles": ["node_modules/**"], "rules": { "import/no-named-as-default": "off" } } ],
    – onuriltan
    Commented Jun 22 at 6:26
38

Ran into this issue because I am using React + Redux:

export class ButtonBack extends React.Component {
  // code removed
}
export default connect(null, null)(ButtonBack);

So with the code above this import will give me a warning:

import ButtonBack from ./ButtonBack;

changing to the following fixes the problem:

import ConnectedButtonBack from ./ButtonBack;

Not exporting class ButtonBack would also fix the problem, but I like to export it to help with testing.


UPDATE 2019

My preferred solution for this issue is to have separate files for components and container. I think this keeps files smaller and easier to understand. In this case I would have two files:

components/ButtonBack.js
containers/ButtonBackContainer.js

UPDATE 2020

The no-named-as-default eslint rule is meant to help you in case you mistakenly import a default export when you meant to import a named export.

I haven't ran into this issue for a while now because:

  • I avoid default exports when I can, as I think they can lead to mild confusion.
  • I don't use the connect function anymore, I use the useSelector hook instead.
  • I usually test the component together with the redux store. Here is an example on how to do that using React Testing Library.
6
  • 1
    another solution would be " import { ButtonBack } from ./ButtonBack; " I prefer this solution if I want to keep the same component name in the import also.
    – arun8
    Commented Jun 7, 2019 at 5:38
  • 1
    @arun8 if you are using redux, thats not a solution. import { ButtonBack } from ./ButtonBack; and import ConnectedButtonBack from ./ButtonBack; are two different things. One is the plain component and the other is the connected component.
    – Doug
    Commented Jun 7, 2019 at 11:55
  • Personally I feel that the calling something "ConnectedButtonBack" is very clunky. Additionally I think having two files that don't serve a hugely different purpose and are directly linked is also clunky. I personally call my pure function _ButtonBack, then export the connected component. That way I can do import { _ButtonBack } if I need the pure version (usually just for tests) and import ButtonBack if I need the connected version. It's less noise than adding the words "Pure" or "Connected" or similar all over the place. Just my opinion! Commented Feb 25, 2020 at 12:09
  • @MattFletcher Naming it _ButtonBack gives the impression it is private and should not be touched. Don't you think that goes against React's design--where we want to have reusable components?
    – Doug
    Commented May 4, 2020 at 23:44
  • 1
    I'm relatively new to React and TS so I'm still bumping into things that might be more obvious to more experienced React/TS developers. The update you made for 2020 ended up being the issue I was running into.
    – WTFranklin
    Commented Jul 27, 2022 at 15:06
24

Original problem line :

import ButtonBack from '../ButtonBack'; 

Fixed Line:

import { ButtonBack } from '../ButtonBack'; 
3
  • 5
    Whilst this may work in the general case, you need to be careful if you are using react/redux, and therefore wrapping your react component in the connect()(yourCompnent) method from redux. If you wrap the export in curly braces, you will not export the connected component.
    – Powderham
    Commented Jun 22, 2018 at 12:00
  • 2
    easy answer, but I don't know what it fixes, since my export was default Commented Jul 6, 2018 at 5:55
  • Nice and Precise Answer...Thanks Commented Jun 30, 2020 at 14:00
6

I had the same issue when I imported class components and it was such a simple solution in the end.

Solution

Just add

"parser": "babel-eslint"

to your eslintrc config file after you installed this package with

npm install babel-eslint --save-dev

or

yarn add babel-eslint --dev

Explanation

babel-eslint tells eslint to use the configuration specified in my Babel configuration file. There I have specified that I use React and that's why eslint will not complain anymore. This is how my Babel configuration file looks like:

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}
3

This is rather silly for esLint but what I did to resolve it was to check file that is exporting, I accidentally had export class then export default connect. Still had lint error, re wrote import line in parent and eslint cleared warning.

3

You could add an exception in .eslintrc

"rules": {
  "import/prefer-default-export": "off"
}
0

You can as well use an alias at export and the opposite alias on import

0

If you really want to have this rule operating, while at the same time avoid it being triggered. You can be explicit about what you want to do.

Importing without the curly brackets, also means importing the default export. So you can be explicit about it like this --

import { default as ButtonBack } from '../ButtonBack'

And this will work even if your ButtonBack does not have a named export for ButtonBack at all, and only has a default export.

A good example might be the debug library in npm/node. It only has a default export, so if you want to avoid getting this error - what you can do is:

import { default as debug } from 'debug'

which will be exactly the same as

import debug from 'debug'

just without the eslint error.

-1

I also encountered this problem while importing faker js I am importing like this:

import faker from '@faker-js/faker'

and getting eslint error:

warning Using exported name 'faker' as an identifier for default export import/no-named-as-default

The solution which worked for me is :

import { faker } from '@faker-js/faker'

So, in your case, you just need to change your importing to this

import {ButtonBack} from '../ButtonBack';

Not the answer you're looking for? Browse other questions tagged or ask your own question.