자바스크립트는 과거 간단한 웹 페이지에 스크립트를 추가하는 용도로 시작되었지만, 점차 대규모 웹 애플리케이션 개발로 확장되었습니다.
이 과정에서 코드를 체계적으로 관리하기 위해 등장한 것이 모듈과 모듈 시스템입니다.
하지만, 이렇게 나뉜 모듈들은 브라우저와 웹 서버 간의 과도한 HTTP 요청을 유발해 성능 저하를 가져오는 문제를 안고 있었습니다.
이 문제를 해결하기 위해 등장한 것이 바로 모듈 번들러(Module Bundler)입니다.
이 글에서는 모듈, 모듈 시스템, 그리고 이를 효과적으로 관리하기 위한 Webpack을 통해 번들링 과정을 알아보겠습니다.
모듈 시스템
자바스크립트는 과거 간단한 웹페이지에 스크립트를 추가하는 용도로 시작했지만, 점차 복잡하고 대규모 웹 애플리케이션으로 확장되면서 코드 파일을 여러 개로 분리해야 할 필요가 생겼습니다.
자바스크립트에서는 이렇게 분리된 파일들 각각을 모듈(module)이라고 부릅니다.
이렇게 나눠진 모듈을 다른 파일에서 사용하기 위해 불러오고 내보내는 방식을 모듈 시스템이라고 합니다.
초기의 모듈
초기에는 HTML에서 <script> 태그를 사용해 자바스크립트 모듈을 불러왔습니다.
추가적인 파일이 필요할 경우, 아래와 같이 <script> 태그를 계속 추가하는 방식이 사용되었습니다.
그러나 이런 방식에는 전역 스코프를 공유한다는 큰 문제가 있었습니다.
위 예시에서 각 파일에서 선언한 number의 값을 다른 파일에서 접근할 수 있음을 확인할 수 있습니다.
그러나 이런 방식은 단일 파일로 관리되면 코드들이 전역 스코프에서 모든 변수가 노출되면서 이름 충돌(Name Collision)등의 문제가 빈번하게 발생했고 개발의 효율성을 떨어트리게 되었습니다.
이러한 문제를 해결하기 위해, 각 파일이 독립적인 스코프를 가지면서도 필요한 모듈을 불러올 수 있는 모듈 시스템이 도입되었습니다.
모듈 시스템의 장점
- 유지보수용이 : 기능들이 모듈화가 잘 되어있는 경우, 의존성을 줄일 수 있기 때문에 기능을 개선이나 수정하기 쉽습니다.
- 네임스페이스화
- 재사용성 : 같은 코드를 반복하지 않고 모듈로 분리시켜 필요할 때마다 재활용할 수 있다.
이런 모듈을 필요시에 언제든지 불러올 수 있도록 하는 다양한 방법들이 있습니다. 이렇게 모듈을 불러오는 방법을 모듈 시스템이라고 하며, 그 모듈 시스템은 다음과 같은 방법들이 있습니다.
모듈 시스템 종류
- AMD : 가장 오래된 모듈 시스템 중 하나로 require.js라는 라이브러리를 통해 처음 개발되었습니다.
- CommonJS : NodeJS 환경을 위해 만들어진 모듈 시스템입니다.
- UMD : AMD와 CommonJS와 같은 다양한 모듈 시스템에서 함께 사용하기 위해 만들어졌습니다.
- ES Module : ES6(ES2015)에 도입된 자바스크립트 모듈 시스템입니다.
ES Module 방식
ES6(ES2015)에 도입된 자바스크립트 모듈 시스템입니다. <script> 태그에 type="module" 속성을 추가해 주면 이 파일은 모듈로서 동작합니다.
- import와 export를 사용하여 모듈을 정의하고 불러옵니다.
- 브라우저와 Node.js에서 모두 지원(단, Node.js에서는 추가 설정 필요).
예시)
// math.js
export const add = (a, b) => a + b;
// main.js
import { add } from './math.js';
console.log(add(2, 3)); // 5
HTML에서 사용
<script type="module" src="main.js"></script>
CommonJS 방식
- Node.js에서 사용되는 기본 모듈 시스템입니다.
- require와 module.exports를 사용하여 모듈을 정의하고 불러옵니다.
// math.js
const add = (a, b) => a + b;
module.exports = { add };
// main.js
const { add } = require('./math.js');
console.log(add(2, 3)); // 5
모듈 번들러
모듈 번들러의 등장 배경
모듈 시스템의 등장으로 파일을 여러 개로 나누어 개발하는 방식이 자리 잡으면서, 웹 애플리케이션은 더욱 체계적으로 관리할 수 있게 되었습니다.
사용자가 브라우저를 통해 웹 서버에 접속하면, 브라우저는 HTML, CSS, JS, 이미지 등 필요한 자원을 요청하고, 웹 서버는 준비된 자원을 응답하여 사용자가 원하는 화면을 볼 수 있도록 합니다.
하지만 개발의 편의성을 위해 모듈을 지나치게 세분화하면, 브라우저가 웹 서버로 요청하는 자원의 양이 많아져 네트워크 비용이 증가합니다. 그 결과 페이지 로딩 시간이 길어지고, 사용자 경험이 저하되는 문제가 발생합니다.
이런 문제를 해결하기 위해 등장한 방법이 바로 "HTTP 요청 횟수를 줄이기"입니다.
이를 통해 네트워크 비용을 줄이고 웹 서비스의 성능을 최적화할 수 있습니다.
개발 단계에서는 코드를 모듈 단위로 나누어 작업하지만, 배포 시에는 여러 개의 모듈을 하나의 JS 파일로 묶어 배포하는 방식이 사용됩니다.
이 방법을 통해 HTTP 요청 횟수를 줄이고, 페이지 로딩 속도를 개선하여 사용자 경험을 크게 향상할 수 있습니다.
이렇게 하나의 JS 파일로 묶는 작업을 "번들링(bundling)"이라고 하고
여러 개의 모듈을 하나의 파일로 묶어주는 도구를 "모듈 번들러(module bundler)" 또는 "빌드도구"라고 합니다.
모듈 번들러의 종류
모듈 번들러는 종류가 매우 다양하지만, 이 글에서는 과거부터 점유율이 높았던 Webpack으로 번들링에 대해 간단히 알아보겠습니다.
최근에는 Vite와 같은 번들러가 빠른 속도와 효율성으로 주목받으며, 점점 더 많은 개발자들에게 채택되고 있는 추세입니다.
Webpack
Webpack은 모듈 번들러로서 기본적으로 JS 파일을 하나의 파일로 묶는 역할을 합니다.
추가로 로더(loader)와 플러그인(plugin)을 사용하면 HTML, CSS, 이미지 등의 압축도 할 수 있습니다.
Webpack으로 번들링 해보기
번들링 하지 않았을 때
- a.js
- b.js
- c.js
- sum.js
- main.js
이렇게 5개의 파일을 브라우저가 웹서버로부터 받아오는 경우에 브라우저는 각 파일을 HTTP 통신으로 받아오게 됩니다.
각 통신마다 비용(시간)이 다 소요되는 것을 알 수 있습니다.
Webpack 설치
1. package.json 구성하기
npm init -y
Webpack의 오픈소스 라이브러리를 설치해야 하므로 package.json을 구성해 주도록 하겠습니다.
2. webpack 설치
npm install --save-dev webpack webpack-cli
webpack은 빌드 과정에서만 사용되고 런타임시에는 필요 없으므로 devDependencies에 추가시킵니다.
3. 번들링 하기
npx webpack --entry ./main.js --output-path ./dist --output-filename bundle.js
로컬환경에 설치된 cli를 실행하기 위해서는 npx 명령어를 사용한다.
(()=>{"use strict";console.log("Result: 1110")})();
그러면./dist 경로에 bundle.js라는 번들링 된 하나의 JS 파일이 생성되게 됩니다.
Webpack 번들링 특징
- 컴파일 타임에 계산 가능한 상수나 수식을 미리 계산하여 결과로 대체하는 최적화합니다.
- 또한 공백과 같은 불필요 부분을 다 없애버리면서 파일 용량을 최적화합니다.
4. 번들링 된 파일로 요청하기
html에서 script 태그에 번들링된 파일을 받아오도록 설정한 후 배포를 시켰습니다.
같은 결과가 나오지만 HTTP 요청이 6개 -> 2개로 줄었고, 로드 속도 또한 60ms 정도 줄어든 것을 볼 수 있습니다.
테스트해 본 JS 파일 자체가 크지 않고 단순하기에 큰 차이가 나지 않았을 수 있지만, 실제 복잡한 웹 애플리케이션이라면 성능 차이가 어마어마하게 날 겁니다.
5. webpack.config.js
Webpack으로 번들링 할 때 명령어를 저렇게 치지 않고 환경설정 파일로 바로 번들링 하는 방법도 있습니다.
//webpack.config.js
const path = require('path'); // 파일 및 디렉토리 경로 설정을 위한 Node.js 내장 모듈
module.exports = {
entry: './main.js', // 번들링의 진입점 파일 경로
output: {
path: path.resolve(__dirname, 'dist'), // 번들 파일이 저장될 디렉토리 (절대 경로 필요)
filename: 'bundle.js', // 생성될 번들 파일 이름
},
};
webpack 환경설정 파일 구성 이후 아래 명령어만 친다면 깔끔하게 번들링을 할 수 있다.
npx webpack
따라서 webpack.config.js 세팅 이후 package.json scripts에 webpack 명령어의 별칭을 붙여주면
//package.json
"scripts": {
"build": "webpack"
},
npm run build 명령어로 바로 빌드 파일을 생성해 낼 수 있습니다.
정리
Webpack은 번들링 과정을 통해 모듈 시스템으로 인해 발생하는 많은 HTTP 요청/응답 수를 최소한을 줄이는 작업을 하는 모듈 번들러입니다.
본 글에서는 Javascript 모듈들을 하나의 파일로 만드는 과정을 보았지만, HTML, CSS 심지어 Image 파일까지 압축시킬 수 있습니다. 더 자세한 정보는 Webpack의 공식문서를 참고하면 될 것 같습니다.
참고
'👨💻 Programming > WEB' 카테고리의 다른 글
Stateless vs Stateful (0) | 2025.02.24 |
---|---|
Virtual DOM이란? React의 렌더링 방식과 CSR, SSR 비교 정리 (1) | 2025.01.13 |
브라우저 화면 렌더링 원리 – DOM, CSSOM부터 Display까지 총정리 (1) | 2024.08.09 |