- Published on
export default를 쓰지 말아야 할 이유
- Author
- Name
- yceffort
export default
구문은 보통 파일 내에서 한개만 export
하거나, 대표로 export
할 것이 있을 때 많이 쓴다.
function Foo {
// ...
}
export default Foo
export default function Foo {
// ...
}
그리고 쓰는 쪽에서는 이렇게 import
할 것이다.
import Foo from './foo'
그런데 왜 이것을 않았으면 좋겠는지 몇 가지 이유를 들어서 설득해보자.
Table of Contents
예제
foo.ts
export default function Foo() {
console.log('foo')
}
bar.ts
export function hello() {
console.log('hello')
}
export function hi() {
console.log('hi')
}
검색이 어렵다.
import { h } from './bar'
default export를 하게 되면 내보내기가 있는지 여부가 불투명하다.
import { Foo } from 'something'
그러나 기본값이 없으면 코드 intellisense로 내부에 어떤 것을 import 할 수 있는지 쉽게 알 수 있다.
commonjs
default
는 commonjs
를 쓰는 사람들에게는 혼동을 준다. 위의 default export를 commonjs
로 바꾸면
export default function Foo() {
console.log('foo')
}
module.exports = {
Foo,
default: Foo,
}
방식으로 해야하는 어려움이 있다.
re-export
export { default as Foo } from './foo'
export * from './bar'
named export 쪽이 다시 export 하는데 있어서 훨씬 편하다.
다이나믹 import
const foo = await import('./foo')
foo.default()
const { hello } = await import('./bar')
hello()
default
한단계를 더 거쳐야 한다.
클래스나 함수가 아니면 한줄이 더 필요함.
// 이건 안된다
export default const hello = 'hello'
// 이건 가능
export const hi = "hi";
// 이렇게 해야한다.
const hello = 'hello'
export default hello
리팩토링의 어려움
default export
는 가져다 쓰는 곳에서 네이밍을 제멋대로 할 수 있으므로, 리팩토링 하기가 어렵다.
import Foo from './foo'
import Wow from './foo'
import Bye from './foo'
위 세개는 모두 동일하게 동작하기 때문에, 오타를 수정하는 등의 작업이 어려워 진다.
트리 쉐이킹
만약 여러개의 object를 하나의 default export
로 내보내는 코드가 있다고 가정해보자.
foo.ts
export default {
foo1: 'foo1',
bar1: 'bar1',
}
bar.ts
export const bar2 = 'bar2'
export const foo2 = 'foo2'
index.ts
import Foo from './foo'
import { foo2 } from './bar'
console.log(Foo.foo1)
console.log(foo2)
이를 트리쉐이킹을 거치게 되면 아래와 같은 결과가 나온다.
var Foo = {
foo1: 'foo1',
bar1: 'bar1',
}
const foo2 = 'foo2'
console.log(Foo.foo1)
console.log(foo2)
named exports
를 하는게 번들 사이즈를 더 줄이는데 도움을 준다.
결론
그럼에도 불구하고 default export를 쓰는 것을 그만두지는 않을 것 같다. eslint-config-airbnb
만 보더라도 내보낼 것이 한개인 경우에는 default를 쓰는 것을 권장하고 있고 nextjs
등의 라이브러리에서도 default export
를 하지 않고서는 할 수 없는 기능들이 더러 있다.
물론 여전히 두 export 방식에 대해서는 논란이 많지만 아무래도 default
가 깔끔한 건 기분 탓일까, 습관 탓일까 🤔
그래도 가급적이면 named exports를 하는 방향으로 코드를 써보자. 그럼에도 default
는 죄가 없는 것 같다.