ホットモジュール置換 (HMR) は、アプリケーションの実行中に、完全な再読み込みなしに、モジュールの交換、追加、または削除を行います。これにより、いくつかの方法で開発速度を大幅に向上させることができます。
HMRの動作を正確に理解するために、いくつかの異なる視点を見ていきましょう...
次の手順により、モジュールをアプリケーションに出入りさせることができます。
このプロセスを自動的に行うようにHMRを設定することも、更新を実行するためにユーザーの操作を要求するように選択することもできます。
通常の資産に加えて、コンパイラは以前のバージョンから新しいバージョンへの更新を許可する「更新」を出力する必要があります。「更新」は2つの部分で構成されています。
マニフェストには、新しいコンパイルハッシュと、更新されたすべてのチャンクのリストが含まれています。これらのチャンクには、更新されたすべてのモジュールの新しいコード(またはモジュールが削除されたことを示すフラグ)が含まれています。
コンパイラは、これらのビルド間でモジュールIDとチャンクIDが一致することを保証します。通常、これらのIDはメモリに格納されます(例:webpack-dev-serverを使用)、しかし、JSONファイルに格納することも可能です。
HMRはオプトイン機能であり、HMRコードを含むモジュールにのみ影響します。1つの例は、style-loader
によるスタイリングのパッチです。パッチが機能するためには、style-loader
がHMRインターフェースを実装します。HMRを介して更新を受け取ると、古いスタイルを新しいスタイルに置き換えます。
同様に、モジュールにHMRインターフェースを実装すると、モジュールが更新されたときに発生するべきことを記述できます。ただし、ほとんどの場合、すべてのモジュールにHMRコードを記述する必要はありません。モジュールにHMRハンドラーがない場合、更新はバブルアップします。これは、単一のハンドラーが完全なモジュールツリーを更新できることを意味します。ツリーの単一のモジュールが更新されると、依存関係のセット全体が再ロードされます。
module.hot
インターフェースの詳細については、HMR APIページを参照してください。
ここでは、少し技術的になります...内部に興味がない場合は、HMR APIページまたはHMRガイドに進んでください。
モジュールシステムランタイムの場合、モジュールのparents
とchildren
を追跡するための追加コードが出力されます。管理側では、ランタイムはcheck
とapply
の2つのメソッドをサポートしています。
check
は、更新マニフェストへのHTTPリクエストを行います。このリクエストが失敗した場合、使用可能な更新はありません。成功した場合、更新されたチャンクのリストが現在ロードされているチャンクのリストと比較されます。ロードされたチャンクごとに、対応する更新チャンクがダウンロードされます。すべてのモジュール更新はランタイムに格納されます。すべての更新チャンクがダウンロードされ、適用準備が整うと、ランタイムはready
状態に切り替わります。
apply
メソッドは、更新されたすべてのモジュールを無効としてマークします。無効なモジュールごとに、モジュールまたはその親に更新ハンドラーが必要です。そうでない場合、無効フラグはバブルアップし、親も無効になります。各バブルは、アプリのエントリポイントまたは更新ハンドラーを持つモジュールに到達するまで(どちらが先になるか)、続きます。エントリポイントからバブルアップした場合、プロセスは失敗します。
その後、無効なモジュールはすべて破棄(破棄ハンドラ経由)され、アンロードされます。その後、現在のハッシュが更新され、すべてのaccept
ハンドラが呼び出されます。ランタイムはidle
状態に戻り、すべてが通常通り続行されます。
HMRは、開発環境でLiveReloadの代替として使用できます。webpack-dev-serverは、ページ全体の再読み込みを試みる前にHMRで更新を試みるhot
モードをサポートしています。詳細はHot Module Replacementガイドを参照してください。