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

ES6 Modules: Named Export vs. Default Export

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

ES6 모듈은 importexport로 파일 사이에서 값을 주고받는다. 값을 내보내는 방법은 이름을 지정하는 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

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