📦 JavaScript 모듈 시스템 완전 정복|ESModules, CommonJS, import/export의 모든 것
안녕하세요, 퍼블리셔 노미입니다!
지금까지 HTML, CSS, JavaScript 기초부터 객체지향, 비동기, 디자인 패턴, 디버깅까지 마스터했죠?
이제 본격적으로 규모 있는 프로젝트를 개발하려면 코드를 기능별로 잘게 나누고, 재사용할 수 있어야 합니다.
그 중심에 있는 것이 바로 **"모듈 시스템(Module System)"** 입니다.
이번 글에서는 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 #모듈설계 #트리셰이킹 #모듈번들링 #퍼블리셔노미 #프론트엔드구조화 #코드관리전략
'차근차근' 카테고리의 다른 글
JavaScript 디자인 패턴 실전편|모듈부터 전략 패턴까지 코드로 배우기 (1) | 2025.05.19 |
---|---|
프론트엔드 개발 환경 완전 정복|Webpack, Vite, Babel로 모던 프로젝트 세팅하기 (1) | 2025.05.18 |
JavaScript 에러 처리와 디버깅 완전 정복|try-catch, throw, 디버깅 실전 방법 (1) | 2025.05.08 |
JavaScript 디자인 패턴 완전 정복|싱글턴, 팩토리, 옵저버 패턴 쉽게 배우기 (2) | 2025.05.07 |
JavaScript 객체지향 프로그래밍 완전 정복|클래스, 프로토타입, 상속 흐름 쉽게 이해하기 (2) | 2025.05.06 |