![]()
JavaScript 코드를 모듈로 구조화하는 현대적 개발 방식
과거에는 하나의 script 파일에 모든 기능을 넣거나, jQuery 플러그인 방식으로 확장하는 경우가 많았다. 그러나 현재 웹 개발에서는 기능 단위로 분리된 모듈 설계가 표준이 되었다. 코드의 가독성, 유지보수성, 확장성을 크게 높여주기 때문이다.
1. 모듈이 필요한 이유
모듈화는 단순히 파일을 여러 개로 나누는 것이 아니다. 기능을 독립적으로 관리하고, 필요할 때만 로드하며, 전역 오염을 방지하는 구조를 만드는 것이다.
- 전역 변수를 최소화할 수 있다.
- 코드를 기능별로 나눠 이해하기 쉽다.
- 재사용성과 확장성이 높아진다.
- 버그 발생 시 원인을 빠르게 찾을 수 있다.
2. ES6 모듈의 기본 구조
모듈은 파일 단위로 구분되며 export와 import 키워드를 사용해 기능을 공유한다.
// util.js
export function qs(selector) {
return document.querySelector(selector);
}
export const VERSION = '1.0.0';
// main.js
import { qs, VERSION } from './util.js';
console.log(qs('.title'), VERSION);
이 방식은 프런트엔드 개발에서 가장 기본적인 모듈 구조이며, 규모가 있는 프로젝트는 대부분 이 방식을 따른다.
3. 공통 유틸 관리 전략
프로젝트를 하다 보면 반복적으로 사용하는 DOM 관련 코드, fetch 래퍼, 날짜 처리 등의 기능이 생긴다. 이를 util.js처럼 별도 파일로 분리해두면 프로젝트 전체에서 재사용할 수 있다.
// fetchWrapper.js
export async function post(url, data) {
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
return res.json();
}
이렇게 하면 모든 페이지에서 같은 통신 패턴을 유지할 수 있다.
4. 기능 단위 모듈 구성
실제 UI 기능을 만들 때는 기능 단위로 모듈을 구분하면 유지보수가 매우 수월해진다. 예를 들어 다음과 같이 구성할 수 있다.
- toggleMenu.js: 메뉴 열기/닫기
- likeButton.js: 좋아요 기능
- bookmarkSort.js: 드래그 정렬
- snsToggle.js: SNS 사용 여부 변경
각 기능을 독립적으로 관리할 수 있으므로 문제 발생 시 해당 모듈만 점검하면 된다.
5. 초기화 흐름 구성
각 모듈이 독립적이라 하더라도 페이지 로드시 어떤 모듈을 실행할지는 명확하게 관리해야 한다. 이런 경우 init.js 같은 파일을 만들어 초기화 흐름을 분리한다.
// init.js
import { initMenu } from './toggleMenu.js';
import { initLike } from './likeButton.js';
window.addEventListener('DOMContentLoaded', () => {
initMenu();
initLike();
});
이렇게 하면 페이지가 로드되면 필요한 기능만 정확하게 실행된다.
6. 전역 오염을 막는 설계
전역 변수는 프로젝트가 커질수록 충돌 위험이 커진다. 모듈을 사용하면 모든 변수와 함수가 파일 내부에 캡슐화되어 전역 오염을 원천적으로 막을 수 있다.
- 전역 네임스페이스를 사용하지 않아도 됨
- 파일 간 변수 충돌 발생이 사라짐
- 예상 가능한 코드 구조 유지
7. 실제 프로젝트에서의 모듈 구조 예시
고즐처럼 다양한 UI 기능이 있는 사이트라면 다음과 같은 구조가 실제로 유효하다.
/js ├─ util/ │ ├─ dom.js │ ├─ fetchWrapper.js │ └─ helper.js ├─ ui/ │ ├─ toggleMenu.js │ ├─ snsToggle.js │ └─ likeButton.js ├─ pages/ │ ├─ home.js │ ├─ admin.js │ └─ promptEditor.js └─ init.js
이 구조는 기능과 목적에 따라 파일이 명확히 분리되어 있어 유지보수가 매우 쉽다.
모듈 설계는 개발 효율을 극적으로 높인다
모듈화를 적용하면 파일 간 의존성이 줄어들고 코드의 흐름이 명확해진다. 특히 다양한 기능이 뒤섞인 프로젝트에서 디버깅 시간이 눈에 띄게 줄어든다. 또한 필요한 파일만 로드할 수 있으므로 성능 관리에도 유리하다.
옵션으로 7편에서는 이러한 모듈 방식을 실제 UI 컴포넌트로 구현해 전체 흐름을 하나로 정리할 것이다.