JavaScript 모듈 시스템의 import와 export

Kingmo·2022년 3월 14일

자바스크립트가 점차 거대해지면서 코드를 여러 파일(모듈)로 분리하고 조립하는 기능이 필수적이 되었다.

ES6(ES2015)부터 표준으로 도입된 ES Modules(ESM)의 핵심인 export와 import 문법을 파악해보자.

1. Export (모듈 내보내기)

모듈 내부에서 선언한 변수, 함수, 클래스 등을 외부 파일에서 접근할 수 있도록 공개하는 문법이다. 크게 Named Export(이름 붙여 내보내기)와 Default Export(기본 내보내기) 두 가지로 나뉜다.

Named Export (여러 개 내보내기)

한 파일 내에서 여러 개의 식별자를 내보낼 수 있으며, 내보낼 때 지정한 이름 그대로 가져와야 한다.

// 선언과 동시에 내보내기
export const myComponent = () => { return <></>; };
export const add = (x, y) => x + y;

// 선언 후 하단에서 객체 형태로 묶어서 내보내기
const subtract = (x, y) => x - y;
const multiply = (x, y) => x * y;
export { subtract, multiply };

Default Export (기본값 하나만 내보내기)

한 파일(모듈)당 단 하나의 값만 기본값으로 내보낼 수 있다.

// 함수 선언문과 함께 내보내기
export default function handleAuth() {
  // 인증 로직
}

// 클래스 컴포넌트 내보내기
export default class App extends React.Component {
  // 컴포넌트 로직
}

// 또는 변수/객체를 기본값으로 내보내기
const config = { apiHost: "https://api.test.com" };
export default config;

2. Import (모듈 가져오기)

외부 파일에서 export된 요소들을 현재 파일의 스코프로 불러온다. 내보낸 방식(Named vs Default)에 따라 불러오는 문법이 다르다.

Named Export 가져오기

중괄호({ }) 안에 내보낸 식별자 명칭을 정확히 기재한다.

import { add, subtract } from './math';

// as 키워드로 별칭(Alias) 지정 가능
import { add as sum } from './math';

Default Export 가져오기

중괄호 없이 자유로운 식별자 이름으로 가져올 수 있다.

import handleAuth from './auth';
import myCustomName from './auth'; // 이름 변경 가능

전체 모듈 한 번에 가져오기 (Namespace Import)

모듈 내에서 export된 모든 요소를 하나의 객체 네임스페이스로 묶어 가져온다.

import * as MathUtils from './math';

MathUtils.add(1, 2);
MathUtils.subtract(5, 3);

문법 대응 요약

내보내기 (Export)가져오기 (Import)특징
export { A, B }import { A, B } from './path'이름이 정확히 일치해야 함 (여러 개 가능)
export default Aimport A from './path'중괄호 없이 임의의 이름으로 수신 가능 (파일당 1개)
export default Aimport { default as A } from './path'Default Export를 명시적 별칭으로 수신하는 형태

3. 모듈 경로 표현과 배럴(Barrel) 패턴

from 뒤에는 가져올 모듈의 상대 경로 또는 절대 경로를 작성한다.

index.js 생략 규칙

자바스크립트 번들러(Webpack)는 특정 폴더 경로를 지정했을 때, 해당 폴더 안의 index.js (또는 index.ts, index.jsx)를 기본 진입 파일로 자동 해석한다.

// 두 구문은 완전히 동일하게 동작한다.
import { Home } from './components/index';
import { Home } from './components';

실무 모듈 재내보내기 (Re-export / Barrel Pattern)

컴포넌트나 페이지가 많아질 때 각 파일을 하나하나 깊은 상대 경로로 불러오면 코드가 지저분해진다. 이를 해결하기 위해 폴더 루트의 index.js에서 한 번에 묶어 재내보내는 방식을 흔히 사용한다.

src/
├── pages/
│   ├── Home/
│   │   └── index.jsx
│   ├── Login/
│   │   └── index.jsx
│   └── index.js      <-- 여러 페이지를 묶어 재내보내는 창구
└── App.jsx

1. 개별 페이지 정의 (pages/Home/index.jsx)

export const Home = () => {
  return <div>Home 화면</div>;
};

2. 진입점에서 한 번에 묶어 재내보내기 (pages/index.js)

export { Home } from './Home';
export { Login } from './Login';

3. 외부 파일에서 깔끔하게 임포트 (App.jsx)

// 일일이 '../pages/Home', '../pages/Login'으로 들어갈 필요 없이 단일 경로에서 구조분해할당으로 임포트
import { Home, Login } from './pages';

export default function App() {
  return (
    <div>
      <Home />
      <Login />
    </div>
  );
}

이 패턴을 적용하면 경로 깊이가 깊어지더라도 임포트 구문이 간결해지고, 내부 폴더 구조가 바뀌어도 외부 호출부 코드를 일일이 수정할 필요가 없어진다.

profile
Developer

0개의 댓글