Hot Reload: 핫 리로드가 개발을 가속화하는 방법

저자: IT Sectr 게시일: 2026-07-03 읽는 시간: 10 분

Hot Reload는 소스 코드의 변경 사항을 페이지를 완전히 다시 로드하지 않고 현재 상태를 잃지 않으면서 실행 중인 애플리케이션에 적용하는 기술입니다. 단순히 전체 페이지를 새로고침하는 Live Reload와 달리, 핫 리로드는 변경된 모듈만 즉석에서 교체합니다. Webpack, 2024에 따르면, Hot Module Replacement(HMR)는 컴포넌트 상태를 보존하여 개발 주기 시간을 최대 80%까지 단축합니다.

핵심 요점

  • Hot Reload는 애플리케이션을 다시 로드하거나 상태를 잃지 않고 코드 변경 사항을 즉시 적용하는 기술입니다.
  • 컴포넌트 상태는 핫 리로드 중에 보존됩니다 — 양식 데이터, 스크롤 위치, 열린 모달 창.
  • HMR(Hot Module Replacement)은 Webpack, Vite 및 기타 번들러에서 Hot Reload를 구현한 것입니다.
  • React Fast Refresh는 React의 공식 구현으로, 함수형 컴포넌트와 훅을 지원합니다.
  • 개발 생산성은 코드 변경과 결과 확인 사이의 시간을 단축하여 향상됩니다.

Hot Reload란?

Hot Reload는 소스 파일의 변경 사항을 애플리케이션을 다시 시작하지 않고 실행 중인 애플리케이션에 즉시 반영하는 개발 메커니즘입니다. 개발자는 에디터에서 코드를 편집하고 파일을 저장하면 결과가 브라우저나 에뮬레이터에 즉시 표시됩니다.

이 기술의 핵심 기능은 애플리케이션 상태를 보존하는 것입니다. 메모리의 변수, 양식의 데이터, 현재 탐색 — 모든 것이 그대로 유지됩니다. 개발자는 필요한 화면으로 돌아가기 위해 일련의 작업을 반복할 필요가 없습니다.

웹 개발에서 Hot Reload는 Hot Module Replacement(HMR) 메커니즘을 통해 구현됩니다. 번들러는 파일 변경을 모니터링하고 영향을 받는 모듈을 확인한 후 WebSocket을 통해 업데이트된 코드를 브라우저로 전송합니다. 브라우저는 페이지를 다시 로드하지 않고 해당 모듈만 교체합니다.

Hot Reload의 인기는 단일 페이지 애플리케이션(SPA)의 확산과 함께 급증했습니다. SPA에서는 전체 페이지를 다시 로드하면 클라이언트 애플리케이션의 모든 상태가 사라집니다. React, Vue, Angular 및 기타 프레임워크는 HMR을 기본 개발 모드로 권장합니다.

번들러 내부에서 HMR이 작동하는 방식

HMR 메커니즘은 네 단계로 구성됩니다. 서버 측의 번들러가 변경된 모듈을 컴파일하고, 새 코드 버전이 포함된 JSON 패치를 생성한 후 WebSocket 연결을 통해 브라우저로 전송합니다. 브라우저 측 HMR 런타임이 패치를 수신하고, 이전 모듈을 새 모듈로 교체한 후 모듈의 구독자에게 알립니다.

컴파일 및 전송 단계

Webpack Dev Server는 클라이언트와 통신하기 위해 WebSocket을 사용합니다. 파일이 변경되면 번들러는 변경 매니페스트와 함께 hot-update.jshot-update.json을 생성합니다. 클라이언트는 JSONP를 통해 이러한 파일을 자동으로 로드합니다.

js
// webpack.config.js - HMR 설정
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  devServer: {
    hot: true,
    liveReload: false
  },
  plugins: [new HtmlWebpackPlugin()]
};

클라이언트에서 모듈 적용

브라우저의 HMR 런타임은 교체 중인 모듈이 accept를 지원하는지 확인합니다. 모듈이 module.hot.accept()를 선언한 경우 런타임은 제자리에서 교체하고 업데이트 콜백을 실행합니다. accept가 선언되지 않은 경우 HMR은 상위 모듈 수준으로 폴백됩니다.

React Fast Refresh에서는 이 로직이 프레임워크 수준에 내장되어 있어 각 파일에 수동으로 module.hot.accept를 작성할 필요가 없습니다. Babel 플러그인 react-refresh/babel이 상태를 잃지 않고 안전하게 컴포넌트를 교체하는 코드를 추가합니다.

Hot Reload, Live Reload 및 Full Reload의 차이

이 세 용어는 종종 혼동되지만 동작이 근본적으로 다릅니다. Live Reload는 변경 시 전체 페이지를 다시 로드합니다 — 모든 상태가 손실됩니다. Full Reload는 개발 서버가 완전히 다시 시작될 때 발생하며 클라이언트뿐만 아니라 서버 상태도 손실됩니다.

유형페이지 리로드상태 보존속도
Hot Reload (HMR)아니요즉시
Live Reload아니요1-3초
Full Reload아니요3-10초

Hot과 Live의 선택은 개발 속도에 직접적인 영향을 미칩니다. HMR을 사용하면 “코드 편집 → 결과 확인” 주기가 50-200ms가 소요됩니다. Live Reload의 경우 1-3초에 컨텍스트 복원 시간이 추가됩니다. 하루 작업 동안 그 차이는 수십 분의 절약된 시간에 달합니다.

React Fast Refresh: React를 위한 기능

React Fast Refresh는 React 컴포넌트에 최적화된 공식 Hot Reload 구현입니다. 불안정하고 수동 구성이 필요했던 이전 React Hot Loader 메커니즘을 대체했습니다. Fast Refresh는 react-refresh/babel을 통해 Create React App, Next.js, Vite 및 Webpack에 내장되어 있습니다.

함수형 컴포넌트 지원

Fast Refresh는 코드가 변경될 때 함수형 컴포넌트의 상태를 올바르게 보존합니다. JSX 마크업만 변경하는 경우 useState 및 기타 훅은 해당 값을 유지합니다. 훅 로직이 변경되면 컴포넌트가 다시 마운트됩니다.

js
// 예제 - JSX 변경 시 상태 보존됨
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}

안전한 교체 규칙

새 코드에 컴파일 오류가 포함된 경우 Fast Refresh는 상태를 보존하지 않습니다. 컴포넌트가 기본 내보내기(default export)가 아닌 named export로 내보내진 경우에도 상태가 보존되지 않을 수 있습니다. 컴포넌트에는 default export를 사용하고 상태 보존을 보장해야 하는 경우 export를 memo로 래핑하는 것이 좋습니다.

HMR을 지원하는 빌드 도구

최신 번들러는 HMR을 제공합니다. Webpack은 devServer.hot을 통한 유연한 구성으로 HMR의 선구자입니다. Vite는 번들링 없이 즉각적인 HMR을 위해 네이티브 ESM과 esbuild를 사용합니다. Parcel은 제로 구성 HMR을 제공합니다. Turbopack은 Rust 기반 HMR을 갖춘 Vercel의 새로운 번들러입니다.

도구HMR 유형구성생태계
Webpack 5WebSocket 통한 HMRdevServer.hot: trueReact, Vue, Angular
Vite네이티브 ESM HMR내장React, Vue, Svelte
Parcel 2제로 구성 HMR필요 없음React, Vue, TS
Turbopack증분 HMR내장Next.js

Vite는 속도에서 두드러집니다 — Vite의 HMR은 브라우저의 네이티브 ES 모듈을 통해 작동합니다. 파일이 변경되면 Vite는 프로젝트 전체를 다시 컴파일하지 않고 import()를 통해 해당 모듈만 전송합니다. Webpack은 각 모듈을 완전히 컴파일하므로 대규모 프로젝트에서 HMR이 느려집니다.

프로젝트의 HMR 구성 예제

다양한 번들러에 대한 HMR 설정을 살펴보겠습니다. Webpack에서는 devServer에 hot: true를 설정하고 react-refresh/babel을 추가해야 합니다. Vite에서는 HMR이 모든 프리셋과 함께 내장되어 작동합니다. Next.js에서는 터보컴파일러를 통해 Fast Refresh가 기본적으로 활성화되어 있습니다.

React와 함께 Vite 사용

js
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  server: {
    hmr: {
      port: 3001
    }
  }
});

Fast Refresh와 함께 Webpack 5 사용

js
// webpack.config.js
const ReactRefreshWebpackPlugin =
  require('@pmmmwh/react-refresh-webpack-plugin');

module.exports = {
  mode: 'development',
  devServer: { hot: true },
  plugins: [new ReactRefreshWebpackPlugin()],
  module: {
    rules: [
      {
        test: /\.jsx?$/u,
        use: 'babel-loader'
      }
    ]
  }
};

핫 리로드의 제한 사항 및 문제점

HMR은 모든 시나리오에서 올바르게 작동하지 않습니다. 동적 클래스를 사용하는 CSS 모듈이 적용되지 않을 수 있습니다. 전역 변수 및 싱글톤(Redux 스토어, 라우터)은 리로드 시 재설정될 수 있습니다. 무거운 라이브러리는 HMR에서 GC 없이 모듈을 교체하여 메모리 누수를 유발할 수 있습니다.

HMR 문제의 해결책은 핫 코드를 부작용이 없는 순수 컴포넌트로 분리하는 것입니다. 부작용(WebSocket 구독, 타이머)은 useEffect에서 정리해야 합니다. Redux의 경우 sessionStorage에 상태를 저장하는 persister가 권장됩니다. CSS Modules 또는 styled-components와 같은 CSS 솔루션은 추가 구성 없이 HMR에서 올바르게 작동합니다.

또 다른 제한 사항은 프로덕션에서의 디버깅입니다. HMR은 프로덕션 빌드에서 의도적으로 비활성화됩니다. 소스 코드가 최소화되고 프로덕션에서 핫 교체가 불가능합니다. 프로덕션에서 오류를 디버깅하려면 HMR이 아닌 소스 맵과 로깅을 사용하세요.

자주 묻는 질문

Hot Reload와 Live Reload의 차이점은 무엇인가요?

Hot Reload는 페이지를 다시 로드하지 않고 변경된 모듈만 교체하며 상태를 보존합니다. Live Reload는 전체 페이지를 다시 로드하여 상태가 손실되고 애플리케이션이 초기 화면에서 다시 시작됩니다.

React에서 Hot Reload를 활성화하려면 어떻게 하나요?

Create React AppVite를 사용하는 프로젝트에서는 HMR이 기본적으로 활성화되어 있습니다. Webpack에서는 devServer: { hot: true } 및 @pmmmwh/react-refresh-webpack-plugin을 추가해야 합니다. Next.js에서는 Fast Refresh가 구성 없이 작동합니다.

Hot Reload가 컴포넌트 상태를 보존하지 않는 이유는 무엇인가요?

원인은 새 코드의 컴파일 오류, default 대신 named export, 훅 서명 변경 또는 직접적인 상태 변이입니다. React Fast Refresh는 올바른 작동을 위해 필요한 경우에만 안전하게 컴포넌트를 재설정합니다.

Hot Reload는 TypeScript에서도 작동하나요?

네, 모든 최신 번들러는 TypeScript에서 HMR을 지원합니다. Vite는 TS 트랜스파일을 위해 esbuild를 사용합니다. Webpack은 @babel/preset-typescript와 함께 ts-loader 또는 babel을 사용합니다. Fast Refresh는 타입이 지정된 컴포넌트에서도 올바르게 작동합니다.

HMR이 변경 사항을 업데이트하지 않을 때 디버깅하는 방법은?

브라우저 콘솔에서 WebSocket 연결 오류를 확인하세요. devServer.hot: true가 활성화되어 있는지 확인하세요. Vite의 경우 HMR 포트를 확인하세요. 문제가 지속되면 전체 페이지를 다시 로드(F5)하고 번들러 콘솔을 확인하세요.

요약

  • Hot Reload는 리로드나 상태 손실 없이 코드를 핫 교체하는 기술로, 현대 SPA 개발의 기초입니다.
  • HMR은 WebSocket 모듈 패치를 통해 구현되며, 전체 재컴파일 없이 변경된 파일만 교체합니다.
  • React Fast Refresh는 훅과 함수형 컴포넌트를 지원하는 React의 공식 HMR 구현입니다.
  • Vite, Webpack 및 Parcel은 HMR을 내장하여 제공하며, Vite는 네이티브 ESM 덕분에 속도에서 앞섭니다.
  • Hot Reload는 모듈이 accept를 선언하거나 Fast Refresh가 default export와 함께 사용되는 경우에만 상태를 보존합니다.
  • 컴파일 오류 및 memo 없는 named export는 핫 교체 중 상태를 재설정할 수 있습니다.
  • Redux 및 전역 상태의 경우 HMR 중 sessionStorage에 데이터를 저장하는 persister가 권장됩니다.

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

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

프로젝트 논의

더 읽어보기