Avoid "export default"
Avoid using export default
as much as possible, for reasons as:
There are a few maintainability concerns as “Rename or Other functionality”
Lets suppose we have foo.ts
like
class Foo {}
export default Foo
Then you will import in bar.ts
import Foo from './foo'
If you rename your class to FoorBar
as below
class FooBar {}
export default FooBar
So bar.ts
will still look the same
import Foo from './foo'
Or when you export another function lets say generateFooBar
, then in your bar.ts
you will have to do a bit of this things:
For Best-Case-Scenario just this:
import Foo, { generateFooBar } from './foo'
Otherwise:
import Foo from './foo'
const generator = Foo.generateFooBar()
Which is an overhead to deal with.
So better to have the solution without default
export class Foo {
}
...
import { Foo } from "./foo";
Discoverability is very poor for default exports
If you write in your import as i do, since i do not remember all the functions, utilities export a line like this:
import {} from './foo'
And try intellisense which every IDE has, good luck with that. Same for autocomplete
With default there is horrible experience for commonJS
Or if you work with commonJS which is one of the hypes
right now you will have to write
const { default } = require('module/foo')
How nice is that?
You don’t get typos like one dev doing
I can import the exported default with many ways, vote for the right solution from provide solutions as below:
import Foo from './foo'
or
import fooDeBar from './foo'
or
import foo from './foo'
etc
Do you get the point?
Auto import quickfix works better
If you use autoimport with default, some IDE with do some tricky stuff which does not end always in correct automport. Cool, now we have to check also this step.
Re-exporting is common for the root index file in npm packages, and forces you to name the default export manually
Lets suppose that we want to do a package, and in our index.ts
we should do the following trick to process with right behaviour of exporting defaults:
export { default as Foo } from './foo'
Not nice, ee? Instead if i do not have default export i can just do:
export * from './foo'
Which work better in your opinion?
Default exports expose themselves badly named as default in dynamic import
We had a use case when writing test for logger package, and we had to do this line of code:
const logger = await import('./logger')
Now to access the functionality of logger we then should do the following just to log a message:
logger.default.log('Something')
Instead without default export would have been something like:
const { log } = await import('./logger')
log('Something')
All things above ensures that all imports follow a uniform pattern
All the import would have the same approach, uniform and easy to remind.
import { Foo } from "./foo";
import { Bar } from "./bar";
...
Keep pushing forward and savor every step of your coding journey.