Reduxでのホットモジュールの交換
公開: 2022-03-11これは、Reduxアプリケーションでのホットモジュール交換(またはHMR)の最小限の例です。 動作するデモコードはGitHubでホストされています。 HMRをサポートするために不可欠な設定のみが含まれているため、独自のReduxアプリケーションにHMRを簡単に適用できます。
HMRの適用を待つことができない場合は、このセクションにジャンプして、5分以内にプロジェクトのHMRを設定してください。
例を実行する
最初に手を汚してください! このサンプルアプリケーションを起動するコマンドを実行する前に、Git、Node.js、およびYarnがマシンに正しくインストールされていることを確認してください。
$ git clone https://github.com/Front-end-io/articles.git $ cd articles && git checkout redux-hmr $ yarn install $ yarn start
次に、http:// localhost:3000 /にアクセスして、機能するかどうかを確認します。
コードを記述すると、ホットモジュールの交換により、完全に更新せずにページを更新できます。 さらに重要なことに、他のリソースが適切に更新されている間、Reduxの状態が維持されます。
ホットモジュールの交換
ホットモジュールの交換は、Webpackが提供する最も便利な機能の1つです。 これにより、JSON、CSS、JSファイルを含むすべての種類のモジュールを、完全に更新しなくても実行時に更新できます。
内部でどのように機能するかを次に示します。
- アプリケーションは、HMRランタイムに更新を確認するように要求します。
- ランタイムは非同期で更新をダウンロードし、アプリケーションに通知します。
- 次に、アプリケーションはランタイムに更新を適用するように要求します。
- ランタイムは同期的に更新を適用します。
HMRは、Reduxアプリケーションを開発する際の生産性を向上させます。 Reduxは、JavaScriptアプリの予測可能な状態コンテナーです。 これは、Reactに基づく非常に人気のある最先端のフレームワークです。 Reduxは、Reduxの第一原理の定義により、単一の共有データストアであり、そのドキュメントでは「信頼できる唯一の情報源」と説明されています。 データストア( reducers
によって更新されるプレーンなJavaScriptオブジェクト)は、ユーザーがアプリケーションを操作すると更新されます。 ボタンのクリック、バックエンドデータの読み込みなど、すべてのユーザー操作により、ストアが複数回更新される可能性があります。 状態の特定のスナップショットでのみバグが発生する場合、バグを修正するのは簡単ではありません。
HMRを使用すると、グローバルストアを再初期化せずにページを更新できます。 Reduxの開発中、一連の操作の後にストアを検査したい場合があります。 非常に一般的なシナリオは、特定の(おそらく複雑な)アイテムをストアに追加した後にのみバグが発生することです。 HMRがない場合は、次の手順を実行する必要があります。
- バグを引き起こす可能性のあるコードを変更します。
- ページを更新し、特定のアイテムをストアに追加します。
- バグが続く場合は、手順1を繰り返します。
バグを見つけるのが難しい場合は、上記の繰り返しが何度も繰り返されます。 現実の世界では、バグはさらに多くの操作を行った後にのみ発生する可能性があります。 HMRは、現在のストア値を変更せずに、変更されたコードをコンパイルして適用するのに役立ちます。 手順2を繰り返す必要はありません。これにより、開発の効率が向上します。
この例の機能
HMR機能を示すためだけに、機能を最小限に抑えたいと考えています。 したがって、このアプリケーションでは、redux-logger、react-router-redux、redux-thunk、redux-devtoolsなどの一般的な機能をReactアプリケーションに組み込みません。一方、1つのレデューサー、2つのアクション、および1つだけを保持します。ページ。
私たちのアプリケーションは、ストアにカウンター値のみを保持します。 ホームと呼ばれるページが1つだけあり、カウンター値と、カウンター値を増減するための2つのボタンが表示されます。
HMRが機能することを確認するには、カウンターを複数回増減してから、コードを変更します。 たとえば、storeのCountertoCounterというタイトルを変更します。 次に、それを見つけます:
- ページは更新されません。
- 表示されるカウンター値は変更されません。
- タイトルが店頭のカウンターに変更されました。
5分でHMRを設定
HMRを設定するには、次の手順に従います。

エッセンシャルライブラリ
HMRをサポートするには、次のライブラリをインストールする必要があります。
- react-hot-loader@^4.2.0:Reactアプリケーションをリアルタイムでコンパイルおよび更新します。
- webpack-dev-server@^3.1.4:Webpackアプリを提供します。 変更時にブラウザを更新します。
ES6
ECMAScript6を使用している場合(最近は誰が使用していませんか?)、ES6をリアルタイムでコンパイルするためのツールがさらに必要です。 まず、これは最小限のES6構成ファイル.babelrcです。
{ "env": { "development": { "presets": [ "react-hmre" ] } } }
リアルタイムコンパイルをサポートするには、次のライブラリが必要です。
- babel-preset-react-hmre@^1.1.1
Webpack.config.js
Webpack構成ファイルwebpack.config.jsでHMRを構成する必要があります。
まず、プラグインセクションでHMRプラグインを有効にします。
"plugins": [ … new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin(), ]
HMRプラグインは、更新されたモジュールをリストするJSONファイルであるマニフェストと、適用されるデータを含むJSONファイルであるUpdateを生成します。 注意すべき点は、HMRはWebpackが提供するオプションです。 HMRインターフェイスを実装するstyle-loaderのようなローダーは、HMRを介して更新を受信し、古いコードを新しいコードに置き換えます。
webpack-dev-serverを使用している場合は、devServerセクションでホットフラグをオンにする必要があります。
"devServer": [ ... hot: true, ]
Reduxレデューサーをホットリロード
Reduxバージョン2.0.0以降、暗黙的なホットリロードによって問題が発生するため、レデューサーは暗黙的にホットリロードされません。 ホットアップデート時にReduxの状態が初期値にリセットされる場合は、レデューサーのホットアップデートを有効にしてみてください。
import { createStore } from 'redux'; import rootReducer from '../reducers/index'; export default function configureStore(initialState) { const store = createStore(rootReducer, initialState); if (module.hot) { // Enable Webpack hot module replacement for reducers module.hot.accept('../reducers', () => { const nextRootReducer = require('../reducers/index'); store.replaceReducer(nextRootReducer); }); } return store; }
高度な設定
HMRのより高度な設定については、HMRAPIを参照してください。
走る
最後に、次のコマンドでアプリケーションを実行してください。
$ ./node_modules/.bin/webpack-dashboard -- webpack-dev-server
トラブルシューティング
HMRは単に変更を適用しません
HMRは、警告なしにサイレントに失敗する場合があります。 コードを更新して保存すると、ページはまったく更新されません。 これはおそらく、システムでそれほど多くのファイル変更を監視できないためです。
Ubuntuでは、 sysctl -a | grep inotify
を実行できます。 sysctl -a | grep inotify
を使用して、現在のuser.max_inotify_watches
値を表示します。 sudo sysctl fs.inotify.max_user_watches=524288
を実行して、この数を増やしてみてください。 または、新しい行fs.inotify.max_user_watches=524288
をファイルsudovim/etc/sysctl.confに追加してから、 sudo sysctl -p /etc/sysctl.conf
/etc/ sudo vim /etc/sysctl.conf
を実行して変更を適用します。