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は、ソースファイルの変更をアプリケーションを再起動することなく、実行中のアプリケーションに即座に反映する開発メカニズムです。開発者はエディターでコードを編集し、ファイルを保存すると、結果がブラウザやエミュレーターに即座に表示されます。

この技術の重要な特徴はアプリケーションの状態を保持することです。メモリ内の変数、フォームのデータ、現在のナビゲーション — すべてがそのまま維持されます。開発者は目的の画面に戻るために一連の操作を繰り返す必要がありません。

Web開発では、Hot ReloadはHot Module Replacement(HMR)メカニズムを通じて実装されます。バンドラーはファイルの変更を監視し、影響を受けるモジュールを特定し、WebSocketを介して更新されたコードをブラウザに送信します。ブラウザはページをリロードせずにそれらのモジュールだけを置き換えます。

Hot Reloadの人気は、シングルページアプリケーション(SPA)の普及とともに高まりました。SPAではページを完全にリロードするとクライアントアプリケーションのすべての状態が失われます。React、Vue、AngularなどのフレームワークはHMRを主要な開発モードとして推奨しています。

バンドラー内部でのHMRの仕組み

HMRメカニズムは4つの段階から構成されます。サーバーサイドのバンドラーが変更されたモジュールをコンパイルし、新しいコードバージョンを含む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の違い

これら3つの用語はしばしば混同されますが、動作は根本的に異なります。Live Reloadは変更があるたびにページ全体をリロードします — すべての状態が失われます。Full Reloadは開発サーバーが完全に再起動されたときに発生し、クライアントだけでなくサーバーの状態も失われます。

タイプページリロード状態保持速度
Hot Reload (HMR)なしあり即時
Live Reloadありなし1~3秒
Full Reloadありなし3~10秒

HotとLiveの選択は開発速度に直接影響します。HMRでは、“コード編集 → 結果確認”のサイクルは50~200ミリ秒です。Live Reloadでは1~3秒にコンテキスト復元時間が加わります。1日の作業では、その差は数十分の時間節約になります。

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は状態を保持しません。コンポーネントがデフォルトでエクスポートされていない場合(named export)、状態も保持されない可能性があります。コンポーネントにはdefault exportを使用し、状態保持を保証する必要がある場合はエクスポートをmemoでラップすることを推奨します。

HMR対応ビルドツール

最新のバンドラーはHMRを提供しています。WebpackはdevServer.hotによる柔軟な設定でHMRのパイオニアです。Viteはバンドルなしで即時のHMRを実現するためにネイティブESMとesbuildを使用します。ParcelはゼロコンフィグHMRを提供します。TurbopackはVercelによるRustベースのHMRを備えた新しいバンドラーです。

ツール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がターボコンパイラーを通じてデフォルトで有効になっています。

ViteとReact

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はts-loaderまたは@babel/preset-typescriptとともに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アプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください