본문으로 건너뛰기
2021. 9. 18·약 3분

ES6 Modules: Named Export vs. Default Export

정육면체가 그려진 문서 더미에서 점선이 세 갈래로 나뉘어 원, 네모, 세모가 담긴 문서 셋으로 이어지는 그림

ES6 모듈은 import와 export로 파일 사이에서 값을 주고받는다. 값을 내보내는 방법은 이름을 지정하는 Named Export와 모듈의 기본값을 정하는 Default Export로 나뉜다. 두 방식의 차이를 중심으로 JavaScript 모듈의 기본 개념을 정리한다.

TL;DR ⚡️​

  • Named Export 특징

    • 한 파일에서 여러 변수, 클래스, 함수를 내보낼 수 있다.
    • 가져올 때 as로 다른 이름을 지정할 수 있다.
  • Default Export 특징

    • 한 모듈에서 하나만 지정할 수 있으며, Named Export와 함께 사용할 수도 있다.
    • 가져올 때는 as 없이 로컬 이름을 자유롭게 정할 수 있다.

사전 지식 📚​

자바스크립트의 모듈(Module)이란?​

모듈은 관련된 코드를 하나의 파일 단위로 묶은 것이다. 코드를 모듈로 나누면 다음과 같은 장점이 있다.

  • 유지보수성: 기능별로 코드를 모으면 수정할 위치와 영향 범위를 찾기 쉽다.
  • 이름 충돌 방지: 모듈마다 독립된 스코프를 사용하므로 전역 공간에서 이름이 겹치는 문제를 줄일 수 있다.
  • 재사용성: 필요한 기능을 다른 파일에서 가져와 다시 사용할 수 있다.

ES 모듈이 표준화되기 전에는 객체 리터럴이나 즉시 실행 함수(IIFE)를 네임스페이스처럼 사용해 전역 이름 충돌을 줄이기도 했다. ES 모듈에서는 파일마다 모듈 스코프가 생기고, import * as name으로 가져온 값은 모듈 네임스페이스 객체로 다룰 수 있다.


자바스크립트에서 모듈을 구현하기 위한 방법들​

  • AMD(Asynchronous Module Definition) 브라우저에서 비동기로 모듈을 불러오기 위해 사용된 규약이며 RequireJS가 대표적인 구현체다.
  • CommonJS 브라우저 밖의 JavaScript 환경을 위해 만들어진 모듈 규약이며 Node.js에서 오랫동안 기본 방식으로 쓰였다. 현재 Node.js는 CommonJS와 ES 모듈을 모두 지원한다.
  • UMD(Universal Module Definition) AMD와 CommonJS 등 여러 모듈 환경에서 같은 코드를 사용할 수 있도록 만든 패턴이다.
  • ES6 (ES2015) ES2015에서 표준 문법으로 도입되었다. 각 모듈이 독립된 스코프를 가지므로 이름 충돌을 막을 수 있다.

Named Export와 Default Export의 차이 🧐​

[1] Named Export (export)​

Named Export는 한 파일에서 여러 값을 이름과 함께 내보낸다. 가져올 때는 중괄호 안에 내보낸 이름을 쓰고, 필요하면 as 뒤에 다른 로컬 이름을 지정한다.

MyComponent.js
export const MyComponent = () => {
// ...
};

export const MyComponent2 = () => {
// ...
};

하나만 가져올 때는 내보낸 이름을 중괄호 안에 쓴다.

main-single.js
import { MyComponent } from "./MyComponent.js";

여러 항목도 한 import 선언으로 가져올 수 있다.

main-multiple.js
import { MyComponent, MyComponent2 } from "./MyComponent.js";

가져오는 파일에서 다른 이름을 쓰려면 as로 별칭을 지정한다.

main-alias.js
import { MyComponent2 as MyNewComponent } from "./MyComponent.js";

모듈이 내보낸 항목을 하나의 모듈 네임스페이스 객체로 가져올 수도 있다.

import * as MainComponents from "./MyComponent.js";

이렇게 가져온 값은 객체의 프로퍼티처럼 점 표기법이나 대괄호 표기법으로 접근한다.

import * as testComponent from "./test.js";

console.log(testComponent.getNumber());
console.log(testComponent.getString());
console.log(testComponent.getBoolean());
console.log(testComponent["getNumber"]());
console.log(testComponent["getString"]());
console.log(testComponent["getBoolean"]());

[2] Default Export (export default)​

한 모듈에서 기본값으로 내보낼 값은 하나만 지정할 수 있다. 함수, 클래스, 객체뿐 아니라 숫자나 문자열도 가능하며 Named Export를 함께 둘 수 있다.

MyDefaultExport.js
const MyComponent = () => {
// ...
};

export default MyComponent;
main.js
import MyDefaultComponent from "./MyDefaultExport.js";

기본 내보내기는 default라는 이름으로 구분되므로 가져오는 쪽의 로컬 이름은 자유롭게 정할 수 있다.


언제 어떤 것을 사용해야 할까?​

  • Named Export는 여러 값을 함께 내보낼 때 알맞다. 가져올 항목을 이름으로 지정하고 필요하면 as로 별칭을 붙인다.
  • Default Export는 모듈을 대표하는 값 하나를 내보낼 때 알맞다. 함수, 클래스, 객체 등 어떤 값이든 기본값으로 지정할 수 있다.

오류 해결​

Cannot use import statement outside a module 오류가 발생하면 실행 환경에 해당 JavaScript 파일이 모듈임을 알려야 한다.

  1. 브라우저에서는 <script type="module" src="./main.js"></script>로 불러온다.
  2. Node.js에서는 package.json에 "type": "module"을 지정하거나 .mjs 확장자를 사용한다.



글과 그림 ⓒ Wonkook Lee

References

좋은 사람들과 재미있는 일을 하며 열정적이고 즐겁게 살고 싶은 개발자