차근차근

JavaScript 모듈 시스템 완전 정복|import/export부터 구조 설계까지 한 번에!

아빠고미 2025. 5. 17. 15:21
반응형

📦 JavaScript 모듈 시스템 완전 정복|ESModules, CommonJS, import/export의 모든 것

안녕하세요, 퍼블리셔 노미입니다!
지금까지 HTML, CSS, JavaScript 기초부터 객체지향, 비동기, 디자인 패턴, 디버깅까지 마스터했죠?

이제 본격적으로 규모 있는 프로젝트를 개발하려면 코드를 기능별로 잘게 나누고, 재사용할 수 있어야 합니다.

그 중심에 있는 것이 바로 **"모듈 시스템(Module System)"** 입니다.

JavaScript 모듈 시스템 완전 정복|import/export부터 구조 설계까지 한 번에!

 

이번 글에서는 ES6의 import/export부터 Node.js의 CommonJS, 그리고 실제 프로젝트에서 모듈을 어떻게 구조화해야 하는지까지 완벽히 정리해드릴게요.


📌 모듈(Module)이란?

모듈이란 코드의 일부분을 **기능 단위로 묶은 독립적인 블록**입니다.
이전에는 모든 JS 코드를 한 파일에 작성했지만, 규모가 커지면서 코드 분할이 필수로 자리 잡았습니다.

모듈을 사용하는 이유

  • 기능별로 파일 분리 가능
  • 코드 재사용성 증가
  • 읽기 쉽고 유지보수 쉬움
  • 전역 스코프 오염 방지

→ 모듈은 효율적인 코드 관리를 위한 필수 전략입니다!


🧱 ESModules (ESM) 기본 문법

ES6(ES2015) 이후 등장한 ESModules는 자바스크립트 표준 모듈 시스템입니다.

1. export 내보내기


// math.js
export const PI = 3.14;

export function add(a, b) {
  return a + b;
}

2. import 가져오기


// main.js
import { PI, add } from './math.js';

console.log(PI);       // 3.14
console.log(add(2, 3)); // 5
  • export 키워드로 내보내고
  • import로 불러옵니다

📤 default export vs named export

ESModules에는 두 가지 내보내기 방법이 있습니다.

1. named export (이름을 지정해서 내보내기)


// user.js
export const name = '노미';
export function greet() {
  console.log('안녕하세요!');
}

// main.js
import { name, greet } from './user.js';

2. default export (하나만 기본으로 내보내기)


// user.js
export default function login() {
  console.log('로그인 처리 중...');
}

// main.js
import login from './user.js';
  • default는 중괄호 없이 import 가능
  • 하나의 파일에서 default export는 1개만 가능

🎭 별칭(Alias)으로 import하기

모듈을 import할 때 이름이 겹치거나 구체화할 필요가 있다면 as 키워드를 사용해서 별칭으로 가져올 수 있어요.


// math.js
export const PI = 3.14;
export const E = 2.71;

// main.js
import * as math from './math.js';

console.log(math.PI); // 3.14

또는 이름 변경도 가능


import { PI as circlePI } from './math.js';
console.log(circlePI); // 3.14

→ 코드 가독성, 충돌 방지에 유용!


📥 동적 import (Dynamic import)

필요한 시점에만 모듈을 불러오고 싶을 때는 import() 함수를 사용합니다. 이건 **Promise**를 반환하므로 **await**와 함께 사용 가능해요.

예시


async function loadModule() {
  const module = await import('./utils.js');
  module.sayHello();
}
  • 초기 로딩 속도 개선
  • 사용자 액션에 따라 모듈 로딩 가능

→ 코드 분할(Code Splitting) 전략의 핵심입니다!


🆚 CommonJS vs ESModules

Node.js 환경에서는 오랫동안 CommonJS (CJS)가 표준이었습니다.
하지만 이제는 ESModules(ESM)이 점점 대세로 자리잡고 있어요.

항목 CommonJS ESModules
내보내기 module.exports export / export default
가져오기 require() import
실행 시점 런타임에서 동기 정적 분석 가능
호환성 Node.js 브라우저 + Node.js (v14~)

CommonJS 예시


// sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;

// app.js
const sum = require('./sum');
console.log(sum(3, 4)); // 7

→ ESM은 앞으로의 표준이기 때문에 브라우저 기반 개발자라면 꼭 익혀야 합니다!


🏗️ 실전 프로젝트에서 모듈 구조 설계하기

모듈화를 제대로 하려면 폴더 구조역할 분리가 명확해야 합니다.

예시 폴더 구조


src/
├── components/
│   ├── Header.js
│   └── Footer.js
├── utils/
│   ├── formatter.js
│   └── validator.js
├── services/
│   └── api.js
├── pages/
│   ├── Home.js
│   └── About.js
└── index.js
  • components/: UI 컴포넌트
  • utils/: 공통 유틸 함수
  • services/: API 연동
  • pages/: 라우트 페이지 단위

→ 기능 단위로 디렉토리를 나누면 유지보수가 훨씬 쉬워집니다!


📁 index.js로 모듈 묶기 패턴

하위 폴더에 여러 모듈이 있을 때, index.js를 사용해 한 번에 묶어서 export할 수 있습니다.

예시: utils/index.js


// utils/formatter.js
export function formatDate(date) { ... }

// utils/validator.js
export function isEmail(value) { ... }

// utils/index.js
export * from './formatter.js';
export * from './validator.js';

사용


import { formatDate, isEmail } from './utils';

→ 모듈 접근을 단순화하고 유지보수성 UP!


📦 모듈 번들링과 Tree Shaking

실제 배포 시에는 여러 모듈을 하나의 파일로 번들링해야 합니다.
이때 webpack, Vite, Rollup 같은 번들러가 사용됩니다.

번들링이 필요한 이유

  • 네트워크 요청 최소화
  • 파일 크기 최적화
  • 모듈 호환성 확보

Tree Shaking

Tree Shaking은 **사용하지 않는 코드(Dead Code)를 제거**하는 기술입니다.
named export만 사용할 경우, 이 기술이 제대로 작동합니다.


// utils.js
export function useMe() {}
export function unusedFunc() {} // 안 쓰면 제거됨

→ 파일 사이즈가 가벼워지고 성능 향상!


🐛 import 오류 디버깅 팁

모듈을 import할 때 흔하게 발생하는 오류를 정리해볼게요.

1. 파일 경로 잘못 지정


import helper from './util/helper.js'; // ❌

import helper from './utils/helper.js'; // ✅

2. 확장자 누락

- 브라우저 기반 ESM은 .js 확장자 명시 필수 - Node.js의 경우 "type": "module" 설정 필요

3. default vs named 헷갈림


// math.js
export default function calc() {}

// main.js
import calc from './math.js'; // ✅
import { calc } from './math.js'; // ❌

→ export와 import 문법 정확히 구분해야 합니다!


📚 마무리하며

JavaScript 모듈 시스템은 현대 개발에서 필수입니다.
이번 글에서 배운 내용을 정리해볼게요:

  • 모듈의 개념과 필요성
  • ESM의 import/export 사용법
  • default export, alias, dynamic import
  • CommonJS와의 차이점
  • 실전 프로젝트 구조 설계
  • index.js로 모듈 집약하기
  • 번들링과 트리 셰이킹의 중요성
  • import 오류 디버깅 전략

다음 글에서는 JavaScript 비동기 모듈 로딩 패턴이나 Webpack & Vite 설정을 통한 모듈 최적화 실전 예제를 이어서 다뤄볼게요!

오늘도 끝까지 읽어주셔서 감사합니다! 함께 성장해요! 🚀


#JavaScript모듈 #importexport #ESModules #CommonJS #모듈설계 #트리셰이킹 #모듈번들링 #퍼블리셔노미 #프론트엔드구조화 #코드관리전략

반응형