[解決済み】WebpackのHot Module Replacementとは一体何ですか?
質問
を読みました。
少ない
ページ
Webpackのホットモジュール置き換えについて。
また
サンプルアプリ
その
使用する
.
これだけ読んでもまだピンとこない。
どうすればいいのでしょうか?
- 開発時のみ使用し、本番では使用しないことを想定しているのでしょうか?
- LiveReloadと同じで、自分で管理する必要があるのでしょうか?
- WebpackDevServerはLiveReloadと何らかの形で統合されているのでしょうか?
CSS(1つのスタイルシート)とJSモジュールをディスクに保存するときに、ページを再読み込みすることなく、またLiveReloadなどのプラグインを使用せずに、更新したいとします。これはHot Module Replacementが助けてくれるものでしょうか?どのような作業が必要で、HMRがすでに提供しているものは何ですか?
どのように解決するのですか?
まず最初に、Hot Module Replacement (HMR)はまだ実験的な機能であることをお知らせします。
HMRは、実行中のアプリケーションでモジュールを交換する(モジュールを追加・削除する)方法です。基本的には、全ページを再読み込みすることなく、変更されたモジュールを更新することができます。
ドキュメンテーション
前提条件
- プラグインを使用する。 https://webpack.js.org/concepts/plugins/
- コードの分割。 https://webpack.js.org/guides/code-splitting/
- webpack-dev-serverです。 https://webpack.js.org/configuration/dev-server/
HMRにはあまり関係ないですが、リンクはこちらです。
- 例 https://webpack.js.org/guides/hot-module-replacement/
- APIです。 https://webpack.js.org/concepts/hot-module-replacement/
これらの回答をドキュメントに追加しておきます。
どのように動作するのですか?
アプリビューから
アプリコードはHMRランタイムにアップデートを確認するよう依頼します。HMRランタイムはアップデートをダウンロードし(非同期)、アップデートが利用可能であることをアプリコードに伝える。アプリコードはHMRランタイムにアップデートを適用するように要求します。 HMRランタイムはアップデートを適用する(sync)。アプリコードはこのプロセスでユーザーのインタラクションを必要とするかしないか(あなたが決めること)。
コンパイラ(webpack)側から見た場合
通常のアセットに加えて、コンパイラは以前のバージョンからこのバージョンへのアップデートを可能にするために "Update" を発行する必要があります。この"Update"には、2つの部分があります。
- アップデートマニフェスト(json)
- 1つまたは複数のアップデートチャンク(js)
マニフェストには、新しいコンパイル ハッシュとすべてのアップデート チャンク (2) のリストが含まれています。
更新チャンクは、このチャンク内のすべての更新されたモジュールのコード(またはモジュールが削除された場合はフラグ)を含んでいます。
コンパイラはさらに、モジュールとチャンクの ID がこれらのビルドの間で一貫していることを確認します。これは、ビルド間でそれらを保存するために "records" json ファイルを使用します(または、メモリ内に保存します)。
モジュールビューから
HMRはopt-in機能なので、HMRのコードを含むモジュールにのみ影響します。ドキュメントには、モジュールで利用可能なAPIが記述されています。一般に、モジュール開発者は、このモジュールの依存関係が更新されたときに呼び出されるハンドラを書きます。また、このモジュールが更新されたときに呼び出されるハンドラも書くことができます。
ほとんどの場合、すべてのモジュールにHMRのコードを書くことは必須ではありません。もし、あるモジュールにHMRハンドラがなければ、更新は泡と消えます。つまり、1つのハンドラで完全なモジュールツリーの更新を処理することができるのです。このツリー内の単一のモジュールが更新されると、完全なモジュールツリーが再ロードされます(再ロードのみ、転送はされません)。
HMRランタイムビューより(技術的)
モジュールシステムのランタイムには、モジュールを追跡するための追加コードが発行されます。
parents
と
children
.
管理側では、ランタイムは2つのメソッドをサポートしている。
check
と
apply
.
A
check
は、更新マニフェストへの HTTP リクエストを行います。この要求が失敗した場合、利用可能なアップデートはありません。それ以外の場合は、アップデートされたチャンクのリストと、現在ロードされているチャンクのリストが比較されます。ロードされた各チャンクについて、対応するアップデートチャンクがダウンロードされます。すべてのモジュール更新は更新としてランタイムに保存される。ランタイムは
ready
状態であり、アップデートがダウンロードされ、適用できる状態にあることを意味します。
Ready 状態の新しいチャンク要求ごとに、アップデートチャンクもダウンロードされます。
は、その
apply
メソッドは、更新されたすべてのモジュールに無効のフラグを立てます。無効なモジュールには、そのモジュールに更新ハンドラ、もしくはすべての親に更新ハンドラが必要です。さもないと、invalid が泡となって出てきて、すべての親モジュールも invalid としてマークされます。このプロセスは、バブルアップが発生しなくなるまで続けられます。エントリポイントまでバブルアップすると、処理は失敗します。
ここで、すべての無効なモジュールは、ディスポーズされ(ディスポーズハンドラ)、アンロードされます。そして、現在のハッシュが更新され、すべての "accept" ハンドラが呼び出されます。ランタイムは
idle
の状態になり、すべてが通常通り行われる。
どんなことができるのですか?
開発現場では、LiveReloadの代わりとして使用することができます。実際、webpack-dev-serverはページ全体を再読み込みする前にHMRで更新しようとするホットモードをサポートしています。必要なのは
webpack/hot/dev-server
のエントリポイントを作成し、dev-serverを呼び出すには
--hot
.
また、アップデートの仕組みとして本番で使用することも可能です。ここでは、HMRをあなたのアプリと統合する独自の管理コードを書く必要があります。
ローダーの中には、すでにホットアップデートが可能なモジュールを生成しているものもあります。
style-loader
はスタイルシートを交換することができます。特別なことをする必要はありません。
CSS(1つのスタイルシート)とJSモジュールをディスクに保存するときに、ページを再読み込みせず、LiveReloadなどのプラグインを使用せずに更新したいとします。これはHot Module Replacementが助けてくれるものなのでしょうか?
はい
どのような仕事が必要で、HMRがすでに提供しているものは何ですか?
ここで少し例を挙げてみましょう。 https://webpack.js.org/guides/hot-module-replacement/
モジュールは、あなたがそれを受け入れる場合のみ、更新することができます。そのため、以下のようにする必要があります。
module.hot.accept
を親または親の親に設定します。例えば、ルーターやサブビューが良い場所です。
webpack-dev-serverだけで使用する場合は、単に
webpack/hot/dev-server
をエントリポイントとして使用します。そうでない場合は、HMRの管理コードとして
check
と
apply
.
ご意見をお聞かせください。何がそんなにかっこいいのか?
- LiveReloadのようなものですが、あらゆる種類のモジュールのためのものです。
- 本番で使える。
- アップデートはコードスプリッティングを尊重し、アプリの使用部分のアップデートのみをダウンロードします。
- アプリケーションの一部に使用することで、他のモジュールに影響を与えることはありません
-
HMRが無効の場合、すべてのHMRコードはコンパイラによって削除されます(ラップは
if(module.hot)
).
注意事項
- 実験的なもので、あまりテストされていない。
- いくつかのバグを期待してください。
- 理論的には本番で使えるが、本格的に使うには時期尚早かもしれない。
-
モジュールIDはコンパイル間で追跡する必要があるので、それを保存する必要があります(
records
). - 最初のコンパイル以降、オプティマイザはモジュールIDをこれ以上最適化できない。バンドルサイズに少し影響します。
- HMR ランタイムコードはバンドルサイズを増加させます。
- 実運用では、HMRハンドラをテストするために、追加のテストが必要です。これはかなり難しいかもしれません。
関連
-
[解決済み】React、Uncaught ReferenceError。ReactDOMは定義されていません
-
[解決済み】Reactのeslintエラーはpropsの検証で見つからない
-
[解決済み】'useState' が定義されていない no-undef React
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] とは何ですか! (not not)演算子とは何ですか?
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] __init__.py は何のためにあるのですか?
-
[解決済み] JSONPとは何か、なぜ作られたのか?
-
[解決済み】JavaScript版sleep()とは?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】React Js: Uncaught (in promise) SyntaxError: 位置 0 の JSON で予期しないトークン < が発生しました。
-
[解決済み】フォームコントロールの値アクセサがない
-
[解決済み】Uncaught ReferenceError: angular is not defined - AngularJSが動作しない。
-
[解決済み] jQueryで、ユーザーがそのフィールドを編集している間、テキストフィールドの最初の文字を大文字にするにはどうすればよいですか?
-
[解決済み】webpack-dev-serverにリモート接続すると、「Invalid Host header」というメッセージが表示されます。
-
[解決済み】XMLHttpRequestモジュールが定義されていない/見つからない
-
[解決済み】XMLパースエラー:ルート要素が見つからない コンソールの場所 FF
-
[解決済み] ローカルファイルを開くことができません - Chrome: ローカルリソースのロードが許可されていません
-
[解決済み】FirefoxでGoogle Maps V3をリモートで使用すると「googleが定義されていません」と表示される。
-
[解決済み】SyntaxError: 期待された式が、'<'を得た。