Webpack 완벽 가이드 | 모듈 번들러·Loaders·Plugins·최적화·실전 활용

Webpack 완벽 가이드 | 모듈 번들러·Loaders·Plugins·최적화·실전 활용

이 글의 핵심

Webpack으로 모듈 번들링을 구현하는 완벽 가이드입니다. Entry, Output, Loaders, Plugins, Code Splitting, Tree Shaking까지 실전 예제로 정리했습니다.

실무 경험 공유: Webpack 설정을 최적화하면서, 빌드 시간이 70% 단축되고 번들 크기가 50% 감소한 경험을 공유합니다.

들어가며: “빌드가 너무 느려요”

실무 문제 시나리오

시나리오 1: 빌드 시간이 10분이에요
최적화가 안 돼 있습니다. Webpack 설정으로 3분으로 단축합니다.

시나리오 2: 번들 크기가 너무 커요
모든 코드가 포함됩니다. Code Splitting과 Tree Shaking으로 줄입니다.

시나리오 3: 설정이 복잡해요
많은 옵션이 있습니다. 핵심만 이해하면 됩니다.


1. Webpack이란?

핵심 특징

Webpack은 모듈 번들러입니다.

주요 장점:

  • 모듈 번들링: 여러 파일을 하나로
  • Loaders: 다양한 파일 처리
  • Plugins: 강력한 확장
  • Code Splitting: 청크 분리
  • Tree Shaking: 사용 안 하는 코드 제거

2. 설치 및 기본 설정

설치

npm install -D webpack webpack-cli webpack-dev-server

webpack.config.js

const path = require('path');

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
    clean: true,
  },
  devServer: {
    static: './dist',
    port: 3000,
    hot: true,
  },
};

package.json

{
  "scripts": {
    "build": "webpack --mode production",
    "dev": "webpack serve --mode development"
  }
}

3. Loaders

CSS Loader

npm install -D style-loader css-loader
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

TypeScript Loader

npm install -D ts-loader typescript
module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
};

Image Loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
    ],
  },
};

4. Plugins

HtmlWebpackPlugin

npm install -D html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      title: 'My App',
    }),
  ],
};

MiniCssExtractPlugin

npm install -D mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
  ],
};

5. Code Splitting

Entry Points

module.exports = {
  entry: {
    main: './src/index.js',
    vendor: './src/vendor.js',
  },
  output: {
    filename: '[name].[contenthash].js',
  },
};

Dynamic Import

// src/index.js
button.addEventListener('click', async () => {
  const module = await import('./heavy-module.js');
  module.doSomething();
});

SplitChunksPlugin

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          priority: 10,
        },
        common: {
          minChunks: 2,
          priority: 5,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

6. 최적화

Production 설정

const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  mode: 'production',
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true,
          },
        },
      }),
      new CssMinimizerPlugin(),
    ],
  },
};

Tree Shaking

// package.json
{
  "sideEffects": false
}

// webpack.config.js
module.exports = {
  mode: 'production',
  optimization: {
    usedExports: true,
  },
};

7. Source Maps

module.exports = {
  devtool: 'source-map', // Production
  // devtool: 'eval-source-map', // Development
};

8. 환경 변수

npm install -D dotenv-webpack
const Dotenv = require('dotenv-webpack');

module.exports = {
  plugins: [
    new Dotenv(),
  ],
};

9. React 통합

npm install -D babel-loader @babel/core @babel/preset-react @babel/preset-env
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
          },
        },
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
};

10. 실전 예제: 풀 설정

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = (env, argv) => {
  const isDevelopment = argv.mode === 'development';

  return {
    mode: argv.mode,
    entry: './src/index.tsx',
    output: {
      filename: '[name].[contenthash].js',
      path: path.resolve(__dirname, 'dist'),
      clean: true,
    },
    module: {
      rules: [
        {
          test: /\.tsx?$/,
          use: 'ts-loader',
          exclude: /node_modules/,
        },
        {
          test: /\.css$/i,
          use: [
            isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader,
            'css-loader',
          ],
        },
        {
          test: /\.(png|svg|jpg|jpeg|gif)$/i,
          type: 'asset/resource',
        },
      ],
    },
    resolve: {
      extensions: ['.tsx', '.ts', '.js'],
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: './src/index.html',
      }),
      new MiniCssExtractPlugin({
        filename: '[name].[contenthash].css',
      }),
    ],
    optimization: {
      minimize: !isDevelopment,
      minimizer: [new TerserPlugin()],
      splitChunks: {
        chunks: 'all',
      },
    },
    devServer: {
      static: './dist',
      port: 3000,
      hot: true,
    },
    devtool: isDevelopment ? 'eval-source-map' : 'source-map',
  };
};

정리 및 체크리스트

핵심 요약

  • Webpack: 모듈 번들러
  • Loaders: 다양한 파일 처리
  • Plugins: 강력한 확장
  • Code Splitting: 청크 분리
  • Tree Shaking: 사용 안 하는 코드 제거
  • 최적화: 빌드 시간, 번들 크기

구현 체크리스트

  • Webpack 설치
  • 기본 설정
  • Loaders 추가
  • Plugins 설정
  • Code Splitting
  • 최적화
  • Source Maps
  • React/Vue 통합

같이 보면 좋은 글

  • Vite 완벽 가이드
  • Turborepo 완벽 가이드
  • Babel 완벽 가이드

이 글에서 다루는 키워드

Webpack, Bundler, Build Tools, Optimization, JavaScript, TypeScript, Frontend

자주 묻는 질문 (FAQ)

Q. Vite와 비교하면 어떤가요?

A. Webpack이 더 성숙하고 플러그인이 많습니다. Vite는 더 빠릅니다.

Q. 학습 곡선이 높나요?

A. 네, 초반에는 어렵지만 익숙해지면 강력합니다.

Q. CRA 없이 React를 설정할 수 있나요?

A. 네, Webpack으로 직접 설정할 수 있습니다.

Q. 프로덕션에서 사용해도 되나요?

A. 네, 대부분의 대규모 프로젝트에서 사용하고 있습니다.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3