So I was always in love with default exports, but unfortunately I think they are a bad practice. It's a little less work to use default exports but I think it's not worth it if you consider the downsides.

Hint: Not saying you should never use default exports, but you should know why you need a default export in that case.

1. No direct export

You can't directly export everything from a file like

export * from './file';

Instead you need to do something like

export { default as foo } from './file';

2. It's clean

It leads to mixed names of functions which in turn makes it hard to find every occurrence in a large scale project, one might be

import doThis from './file';

another might be

import doThat from './file';

whereas if you use named exports it will always be

import { doThis } from './file';

or at least

import { doThis as doThat } from './file';

3. It increases productivity

While default exports require less code, constant named exports require less thinking. You will just always require anything via named imports. While you can do that with named exports, because they will always work for (almost) everything, you won't be able this with default exports. This saves time.

4. Tree shaking

If you want to just get a single property of an object, you should never export a huge object and destructure it, as this bloats your bundle. So instead of doing this:

export default { something, somethingelse, }

you should do this:

export const something = ...; export const somethingelse = ...;

Bundlers like webpack will be able to understand your code and remove the parts you don't need from your bundle.

5. Meaningful errors

If you import the whole file there will most likely be no error because the export was not found. On the other hand if you import a named export you will probably already get an error right in your IDE saying that the export could not be found in the given file.

How to achieve this?

I think the best way is just to configure the linter to throw an error when you use default exports. Add this to your eslint config:

"import/no-default-export": 2,

and if you run the linter you will get something like: