Skip to content

Webpack: 가장 대표적인 번들러

Webpack은 자바스크립트 애플리케이션을 위한 정적 모듈 번들러로, Entry, Output, Loaders, Plugins, Mode의 5대 핵심 개념을 기반으로 모든 종류의 에셋을 의존성 그래프로 관리하고 번들링한다.

학습 목표

  • Webpack의 핵심 역할과 등장 배경을 이해한다
  • Webpack의 5대 핵심 개념(Entry, Output, Loaders, Plugins, Mode)을 설명할 수 있다
  • Webpack이 다양한 모듈 시스템(CommonJS, ESM, AMD)을 지원하는 방식을 파악한다
  • webpack.config.js 기본 설정을 작성할 수 있다
  • Module Federation Plugin의 존재와 마이크로프론트엔드에서의 의의를 안다

1. Webpack이란?

Webpack 공식 사이트의 메인 이미지는 다양한 종류의 파일(.js, .ts, .css, .png, .json 등)이 Webpack을 통과하여 정적 에셋(static assets)으로 변환되는 모습을 보여준다. Webpack의 핵심 역할을 한 마디로 요약하면 **"의존 관계가 있는 모듈들을 정적 에셋으로 번들링"**하는 것이다.

1.1 Webpack이 필요한 이유

프론트엔드 개발 역사를 따라가면 번들러가 왜 필요한지 자연스럽게 이해된다.

시기방식문제점
초기<script> 태그 나열전역 스코프 충돌, 순서 관리 어려움
IIFE 시대즉시 실행 함수로 스코프 분리최적화 어려움, 사용 여부 확인 불가
CommonJSrequire()/module.exports브라우저 미지원, 동기적 로딩
ES Moduleimport/export브라우저 지원 불완전, 번들링이 여전히 더 효율적
Webpack모든 모듈 시스템 지원 + 에셋 번들링설정 복잡성 (이후 도구들이 해결)

2. Webpack의 5대 핵심 개념

Webpack을 이해하는 데 있어 반드시 알아야 할 5가지 핵심 개념이 있다.

2.1 Entry (진입점)

Entry는 Webpack이 내부 의존성 그래프를 생성하기 위해 사용하는 시작 모듈이다. 이 진입점에서 직접적/간접적으로 의존하는 모든 모듈과 라이브러리를 추적한다.

javascript
// 단일 진입점 (기본값: src/index.js)
module.exports = {
  entry: './src/index.js'
};

// 다중 진입점
module.exports = {
  entry: {
    app: './src/app.js',
    admin: './src/admin.js'
  }
};

2.2 Output (출력)

Output은 생성된 번들을 내보낼 위치파일명을 지정한다.

javascript
const path = require('path');

module.exports = {
  output: {
    filename: '[name].[contenthash].js',  // 캐시 버스팅
    path: path.resolve(__dirname, 'dist'),
    clean: true  // 빌드 전 dist 폴더 정리
  }
};

2.3 Loaders (로더)

Webpack은 기본적으로 JavaScript와 JSON만 이해한다. 로더는 그 외의 파일을 Webpack이 처리할 수 있는 모듈로 변환한다. module.rules에서 test(대상 파일)와 use(적용할 로더)를 쌍으로 정의한다.

javascript
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,    // 대상 파일
        exclude: /node_modules/,
        use: 'babel-loader'             // 적용할 로더
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']  // 오른쪽에서 왼쪽으로 적용
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        type: 'asset/resource'          // Webpack 5 내장 에셋 모듈
      }
    ]
  }
};

주요 로더:

로더역할
babel-loaderBabel을 통한 JS/TS 트랜스파일
swc-loaderSWC를 통한 고속 트랜스파일
ts-loaderTypeScript 컴파일 (타입 검사 포함)
css-loaderCSS를 JS 모듈로 변환
style-loaderCSS를 DOM에 <style> 태그로 주입
sass-loaderSCSS/SASS → CSS 변환
file-loader파일을 출력 디렉토리에 복사 (Webpack 4)

2.4 Plugins (플러그인)

플러그인은 번들 최적화, 에셋 관리, 환경 변수 주입 등 로더로는 수행할 수 없는 광범위한 작업을 처리한다.

javascript
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { DefinePlugin } = require('webpack');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({ template: './src/index.html' }),
    new MiniCssExtractPlugin({ filename: '[name].[contenthash].css' }),
    new DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') })
  ]
};

주요 플러그인:

플러그인역할
HtmlWebpackPluginHTML 파일 생성, 번들 자동 삽입
MiniCssExtractPluginCSS를 별도 파일로 추출
DefinePlugin컴파일 타임 상수/환경변수 정의
TerserPluginJavaScript 코드 압축 (production 기본 포함)
CopyWebpackPlugin정적 파일을 출력 디렉토리에 복사
ModuleFederationPlugin마이크로프론트엔드 런타임 모듈 공유

2.5 Mode (모드)

Mode는 빌드 환경에 따른 Webpack의 내장 최적화를 활성화한다.

모드내장 동작
development상세한 에러 메시지, 소스맵 활성화, 빠른 리빌드
productionTree Shaking, 코드 압축(TerserPlugin), 최적화 활성화
none내장 최적화 비활성화

3. webpack.config.js 전체 예시

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

module.exports = {
  mode: 'production',

  entry: './src/index.tsx',

  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist'),
    clean: true
  },

  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js']
  },

  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        exclude: /node_modules/,
        use: 'swc-loader'  // Babel 대신 SWC 사용
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html'
    })
  ],

  devServer: {
    port: 3000,
    hot: true  // Hot Module Replacement
  }
};

4. Module Federation Plugin (개요)

Webpack 5에서 도입된 Module Federation은 런타임에 서로 다른 빌드의 모듈을 공유할 수 있게 해주는 기능이다. 마이크로프론트엔드 아키텍처에서 핵심적인 역할을 한다.

javascript
// 간략 예시 (상세는 챕터 09에서 다룸)
const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'app1',
      remotes: { app2: 'app2@http://localhost:3002/remoteEntry.js' },
      shared: ['react', 'react-dom']
    })
  ]
};

Module Federation의 상세한 내용은 챕터 09: 모듈 페더레이션에서 전용으로 다룬다. 여기서는 Webpack이 마이크로프론트엔드 런타임 통합의 유일한 공식 도구라는 점만 기억하자.


5. Webpack의 장단점

장점단점
가장 넓은 생태계와 플러그인설정이 복잡하다
모든 모듈 시스템(CJS, ESM, AMD) 지원빌드 속도가 상대적으로 느리다
Module Federation 공식 지원러닝 커브가 높다
HMR, 코드 분할, 지연 로딩 완벽 지원작은 프로젝트에는 과도하다
거의 모든 프레임워크와 호환초기 설정 보일러플레이트가 많다

5.1 성능 개선 전략

전략효과
babel-loaderswc-loader 교체트랜스파일 속도 10~20배 향상
cache 옵션 활성화 (Webpack 5)재빌드 시 변경된 모듈만 처리
thread-loader 사용멀티 스레드 병렬 처리
DllPlugin 활용변경되지 않는 의존성 사전 빌드
splitChunks 최적화공통 모듈 분리로 캐시 효율 향상

핵심 정리

개념핵심 내용
Webpack모든 종류의 에셋을 의존성 그래프로 관리하는 정적 모듈 번들러
Entry의존성 그래프의 시작점. 기본값 src/index.js
Output번들 출력 위치와 파일명 지정
Loaders비JS 파일을 Webpack이 이해하는 모듈로 변환
Plugins번들 최적화, 에셋 관리 등 광범위한 확장 기능
Modedevelopment/production에 따른 내장 최적화 전환
Module Federation마이크로프론트엔드 런타임 모듈 공유 (챕터 09에서 상세)

다음 단계

  • 다음 문서 07-Vite.md에서 ESM 기반 개발 서버와 Rollup 프로덕션 빌드를 결합한 차세대 프론트엔드 도구 Vite의 원리와 사용법을 학습한다.