Bundler — 정의, 유형 및 작동 원리

저자: IT Sectr 게시일: 2026-05-19 읽는 시간: 8 분

Bundler는 여러 JavaScript 모듈을 하나 또는 여러 파일로 결합하여 브라우저나 모바일 애플리케이션에서 사용할 수 있도록 하는 빌드 도구입니다. 최신 번들러(Webpack, Metro, Vite)는 파일을 결합할 뿐만 아니라 트랜스파일, 축소 및 리소스 최적화도 수행합니다. Webpack Concepts (2026)에 따르면, 적절한 번들러 구성은 기능 손실 없이 빌드 크기를 40~60% 줄입니다.

핵심 포인트

  • Bundler는 JavaScript 모듈과 그 종속성을 배포를 위해 최적화된 파일로 결합하는 프로그램입니다.
  • Webpack은 모든 빌드 작업을 위한 로더와 플러그인의 풍부한 생태계를 갖춘 가장 인기 있는 번들러입니다.
  • Metro는 React Native의 기본 번들러로, 모바일 애플리케이션 개발에 최적화되어 있습니다.
  • Vite는 빠른 개발을 위해 네이티브 ES 모듈을 사용하고 프로덕션 빌드에는 Rollup을 사용하는 차세대 번들러입니다.
  • 번들링에는 트랜스파일, 축소, 코드 분할 및 종속성 관리가 포함됩니다.

Bundler란 무엇인가?

Bundler(모듈 번들러)는 진입점(애플리케이션의 메인 파일)을 받아 모든 종속성을 재귀적으로 탐색하여 모듈 그래프를 구축하는 명령줄 도구입니다. 출력으로 번들러는 HTML 페이지에 포함하거나 모바일 애플리케이션에서 실행할 수 있는 하나 이상의 파일을 생성합니다.

현대 개발에서 번들러가 필요한 이유

오랫동안 브라우저는 플랫폼 수준에서 JavaScript 모듈 시스템을 지원하지 않았습니다. Bundler는 수백 개의 importrequire를 단일 파일로 변환하여 이 문제를 해결했습니다. 오늘날 브라우저에서 ES 모듈을 기본 지원함에도 불구하고 번들러는 추가 작업을 수행합니다: JSX 및 TypeScript 트랜스파일, 코드 축소, 지연 로딩을 위한 코드 분할 및 개발 속도 향상을 위한 핫 모듈 교체(HMR).

모바일 개발에서 React Native는 기본 번들러로 Metro를 사용하고, Flutter는 Dart 기반의 자체 빌드 시스템을 사용합니다. 번들러 선택은 개발 속도, 애플리케이션 크기 및 런타임 성능에 직접적인 영향을 미칩니다.

번들링의 작동 방식

번들링은 여러 단계를 거칩니다: 입력 파일 파싱, 종속성 그래프 구축, 모듈 변환 및 출력 파일 생성. 각 단계에서 번들러는 소스 코드 변환을 위한 로더와 최적화를 위한 플러그인을 적용합니다.

파싱 및 종속성 그래프 단계

번들러는 진입점에서 시작하여 파일을 읽고 AST(추상 구문 트리)를 구축합니다. AST에서 모든 importrequire 문이 추출됩니다. 발견된 각 import에 대해 번들러는 모든 종속성이 단일 그래프에 수집될 때까지 프로세스를 재귀적으로 반복합니다.

js
// 번들러의 간소화된 구현
const fs = require('fs');
const path = require('path');

function buildGraph(entry) {
  const content = fs.readFileSync(entry, 'utf-8');
  const imports = content.match(/require\(['"](.+?)['"]\)/g);
  const modulePath = path.resolve(path.dirname(entry), imports[0]);
  return { entry, content, deps: [buildGraph(modulePath)] };
}

그래프를 구축한 후 번들러는 로더(파일을 JavaScript로 변환: TypeScript → JS, SCSS → CSS, JSX → JSX 함수)를 적용합니다. 그런 다음 플러그인이 추가 변환(축소, 이미지 인라인, 서비스 워커 생성)을 수행합니다.

번들러의 주요 유형

번들러는 세 가지 세대로 나뉩니다: 클래식, 특수화, ES 모듈 기반 차세대. 각 유형은 고유한 아키텍처와 적용 영역을 가지고 있습니다.

클래식 번들러

Webpack은 거대한 생태계를 가진 가장 널리 사용되는 번들러입니다. 주요 장점은 유연성입니다: 수천 개의 로더와 플러그인이 거의 모든 빌드 시나리오를 지원합니다. Parcel은 제로 구성 접근 방식을 제공하며 파일 확장자에 따라 필요한 변환을 자동으로 감지합니다. 두 번들러 모두 코드 분할과 HMR을 지원합니다.

특수화 번들러

Metro는 React Native 전용으로 만들어졌으며 JavaScript 및 TypeScript에서만 작동합니다. 아키텍처는 모바일 개발에 최적화되어 있습니다: 인라인 require, 비동기 모듈 로딩 및 Hermes 엔진 통합을 지원합니다. Rollup은 라이브러리와 npm 패키지에 중점을 두며 불필요한 래퍼 없이 깔끔한 ES 모듈 출력을 생성합니다.

Webpack, Metro, Vite 비교

번들러 선택은 플랫폼과 프로젝트 요구 사항에 따라 다릅니다. Webpack은 다목적이지만 상세한 구성이 필요합니다. Metro는 React Native의 유일한 옵션입니다. Vite는 네이티브 ES 모듈 덕분에 가장 빠른 개발 경험을 제공합니다.

특징WebpackMetroVite
플랫폼웹, 범용React Native웹, 범용
개발 빌드 속도중간높음매우 높음
코드 분할
HMRFast Refresh즉시 HMR
플러그인 생태계거대함제한적성장 중
구성복잡함간단함간단함
TypeScript 지원로더 통해내장내장

Vite는 종속성 사전 번들링에 esbuild를 사용하고 프로덕션 빌드에 Rollup을 사용하여 개발 모드에서 Webpack보다 5~10배 빠른 속도 향상을 제공합니다. Metro는 웹 대상을 지원하지 않지만 React Native 브리지 및 Turbo Modules와 완벽하게 통합됩니다.

프로젝트에서 번들러 구성

구성은 다양한 파일 유형이 처리되는 방식, 빌드가 생성되는 위치 및 적용되는 최적화를 결정합니다. 일반적인 구성 파일에는 진입점, 모듈 규칙, 플러그인 및 출력 설정이 포함됩니다.

React Native 웹 프로젝트용 Webpack 구성 예제

js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react'] } },
      },
      { test: /\.css$/, use: ['style-loader', 'css-loader'] },
    ],
  },
  plugins: [new HtmlWebpackPlugin({ template: './public/index.html' })],
  devServer: { port: 3000, hot: true },
};

Metro는 구성을 위해 별도의 파일 metro.config.jsbabel.config.js를 사용합니다. Webpack과 달리 Metro의 구성은 훨씬 간단합니다. 번들러가 React Native에 특화되어 스타일이나 이미지에 대한 로더를 구성할 필요가 없기 때문입니다.

일반적인 빌드 오류

숙련된 개발자도 번들링 오류를 경험합니다. Duplicate module은 가장 일반적인 문제 중 하나로, package.json의 버전 비호환성으로 인해 동일한 종속성이 번들에 여러 번 포함됩니다. Module not found는 import 경로가 잘못되었거나 패키지가 설치되지 않은 경우 발생합니다.

Metro 특정 오류

Metro는 모바일 기기의 번들 크기에 제한이 있습니다. 2~5MB 제한을 초과하면 기기 메모리 부족으로 Unable to resolve module 오류가 발생합니다. 해결책은 inline requiresRAM bundles를 사용하여 모듈을 지연 로딩하는 것입니다. Metro는 심볼릭 링크에도 민감하므로 모노레포에서는 구성에 추가 watchFolders 설정이 필요합니다.

Webpack의 일반적인 문제는 Module parse failed로, 파일 형식이 예상치 못한 경우나 필요한 로더가 없을 때 발생합니다. 파일 확장자를 확인하고 module.rules에 적절한 규칙을 추가하면 문제가 해결됩니다. source-map-explorer를 사용하면 최종 번들에서 중복 모듈과 불필요한 종속성을 찾는 데 도움이 됩니다.

빌드 속도 향상을 위한 구성 최적화

느린 빌드는 번들러 작업 시 주요 문제 중 하나입니다. 속도를 높이려면 실행 간 모듈 변환 결과를 저장하는 영구 캐싱을 사용하세요. Webpack 5는 cache: { type: 'filesystem' }을 통한 파일 캐싱을 지원하고, Vite는 사전 번들링에 esbuild를 사용하며, Metro는 메모리 내 모듈 캐싱에 의존합니다. 또한 로더에서 node_modules에 exclude를 지정하여 이미 빌드된 패키지를 다시 처리하지 않도록 합니다.

코드 분할 전략 선택

코드 분할(Code splitting)은 번들을 필요 시 로드되는 청크로 나눕니다. 각 번들러는 이 전략을 다르게 구현합니다. Webpack은 동적 import import()를 지원하여 각 모듈에 대해 별도의 청크를 만듭니다. Metro는 지연 로딩을 위해 inline requires를 사용합니다. Vite는 추가 구성 없이 공급업체 청크와 동적 import를 자동으로 분할합니다. 전략 선택은 프로젝트 요구 사항에 따라 다릅니다: 모바일 애플리케이션의 경우 지연 로딩이 있는 더 작은 초기 번들이 선호됩니다.

React Native에서 코드 분할이 올바르게 작동하려면 추가 구성이 필요합니다: Metro를 inlineRequires를 통해 비동기 청크용으로 구성해야 합니다. Webpack과 Vite에서는 동적 import() 구문을 사용하면 코드 분할이 기본적으로 작동하여 자동으로 분할 지점이 생성됩니다. 최대 효율을 위해 중요한 청크에 <link rel="preload">를 통한 사전 로드 힌트와 코드 분할을 결합하세요.

자주 묻는 질문

현대 애플리케이션에 번들러가 필수인가요?

JSX, TypeScript 또는 CSS 모듈이 없는 간단한 프로젝트의 경우 브라우저에서 네이티브 ES 모듈을 사용할 수 있습니다. 그러나 프로덕션 빌드의 경우 번들러는 축소, 트리 쉐이킹 및 코드 분할을 제공하며 이는 성능에 중요합니다. 번들러 없이는 대규모 프로젝트에서 모듈식 아키텍처를 유지하기 어렵습니다.

새 프로젝트에는 어떤 번들러를 선택해야 하나요?

React Native의 경우 — Metro(유일하게 지원되는 옵션). 웹 애플리케이션의 경우 — 새 프로젝트에는 Vite(속도 때문), 기존 프로젝트에는 Webpack(풍부한 생태계). 라이브러리 및 npm 패키지의 경우 — Rollup(깔끔한 ES 모듈 출력 생성).

번들러가 모바일 앱 크기에 어떤 영향을 미치나요?

번들러는 최종 JS 번들 크기를 직접 결정합니다. 트리 쉐이킹을 사용하는 Webpack은 크기를 30~50% 줄일 수 있습니다. React Native용 Metro는 Hermes 바이트코드를 지원하여 일반 JavaScript보다 크기를 20~30% 줄입니다. 코드 분할을 통해 필요 시 모듈을 로드하여 초기 번들을 줄일 수 있습니다.

웹과 모바일 플랫폼의 번들링 차이점은 무엇인가요?

웹의 경우 번들러는 다양한 브라우저와 호환되는 코드를 생성하고 CSS, 이미지 및 글꼴을 지원합니다. 모바일 플랫폼의 경우 Metro는 JavaScript 엔진(Hermes 또는 JSC)용 코드를 생성하고 CSS나 HTML을 처리하지 않으며 제한된 기기 리소스에 맞게 빌드를 최적화합니다.

하나의 프로젝트에서 여러 번들러를 사용할 수 있나요?

네, 일부 프로젝트는 웹 부분에 Webpack을 사용하고 React Native에 Metro를 사용합니다(예: 공유 코드베이스가 있는 모노레포). 그러나 이는 CI/CD 구성을 복잡하게 만들고 종속성 버전 동기화가 필요합니다. 가능하면 모든 대상에 단일 번들러를 사용하는 것이 좋습니다.

요약

  • Bundler는 브라우저나 모바일 애플리케이션용으로 JavaScript 모듈을 최적화된 파일로 결합하는 도구입니다.
  • Webpack은 가장 큰 로더 및 플러그인 생태계를 가진 범용 번들러입니다.
  • Metro는 React Native의 표준 번들러로, 모바일 개발에 최적화되어 있습니다.
  • Vite는 네이티브 ES 모듈과 Webpack보다 5~10배 빠른 개발 서버를 갖춘 차세대 번들러입니다.
  • 번들링에는 파싱, 종속성 그래프 구축, 트랜스파일 및 출력 파일 생성이 포함됩니다.
  • 트리 쉐이킹코드 분할은 최종 번들 크기를 줄이는 핵심 최적화입니다.
  • React Native의 경우 Metro가 유일한 옵션입니다. 웹 프로젝트의 경우 요구 사항에 따라 Vite 또는 Webpack을 선택하세요.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기