export default
can lead to problems
Let’s go with an example. Consider you have a file foo.ts
with the following contents:
class Foo {
}
export default Foo;
You would import it (in bar.ts
) using ES6 syntax as follows:
import Foo from "./foo";
There are a few maintainability concerns here:
- If you refactor
Foo
infoo.ts
it will not rename it inbar.ts
. - If you end up needing to export more stuff from
foo.ts
(which is what many of your files will have) then you have to juggle the import syntax.
For this reason I recommend simple exports + destructured import. E.g. foo.ts
:
export class Foo {
}
And then:
import {Foo} from "./foo";
Bonus points: Discoverability is very poor for default exports. You cannot explore a module with intellisense to see if it has a default export or not.
Bonus points: You even get autocomplete at this
import {/*here*/} from "./foo";
cursor location. Gives your developers a bit of wrist relief.Bonus points: Better commonJs experience. With
default
there is horrible experience for commonjs users who have toconst {default} = require('module/foo');
instead ofconst {Foo} = require('module/foo')
Bonus points: You don’t get typos like one dev doing
import Foo from "./foo";
and another doingimport foo from "./foo";
Bonus points: Auto import quickfix works better. You use
Foo
and auto import will write downimport { Foo } from "./foo";
cause its a well defined name exported from a module.Bonus points: Re-exporting is unnecessarily hard. Re-exporting is common for the root
index
file in npm packages e.g.import Foo from "./foo"; export { Foo }
(with default) vs.export * from "./foo"
(with named exports).