HMR

Hot module replacement

Hot module replacement(HMR)は、JavaScriptモジュールを修正後に再読み込みするプロセスを指します。プロセス全体を再起動する必要がないため、HMRは通常、より迅速なフィードバックループをもたらします。

HMRという用語は、Viteなどのツールがモジュールをホットリロードし、既存の状態を維持しながらウェブページに変更を適用するフロントエンドエコシステムで長年使用されてきました。

ただし、AdonisJSによるHMRは、ViteやWebpackなどのツールとは大きく異なり、はるかにシンプルです。HMRの目的は、高速なリロードを提供することです。

キーコンセプト

ブラウザへの更新は伝播されません

AdonisJSはバックエンドフレームワークであるため、フロントエンドアプリケーションの状態を維持したり、ウェブページにCSSを適用したりすることは担当していません。したがって、私たちのHMR統合はフロントエンドアプリケーションと通信し、その状態を調整することはできません。

実際、すべてのAdonisJSアプリケーションがブラウザでレンダリングされるウェブアプリケーションではありません。多くのアプリケーションは純粋なJSON APIを作成するためにAdonisJSを使用しており、彼らも私たちのHMR統合の恩恵を受けることができます。

動的インポートのみ動作します

多くのHMRツールは、コード変換を使用してコンパイルされた出力に追加のコードを注入します。AdonisJSでは、トランスパイラにはあまり賛成しておらず、プラットフォームをそのまま受け入れることを常に心がけています。したがって、私たちのHMRのアプローチはNode.jsのローダーフックを使用し、動的インポートのみ動作します。

良いニュースは、AdonisJSアプリケーションのすべての重要な部分がデフォルトで動的にインポートされるということです。たとえば、コントローラ、ミドルウェア、イベントリスナーなどはすべて動的にインポートされるため、アプリのコードを変更することなく、今日からHMRを活用できます。

動的にインポートされるモジュールのインポートは、トップレベルに配置することもできます。たとえば、ルートファイルで動的にインポートされるコントローラは、バリデータ、TSXファイル、モデル、サービスのトップレベルのインポートを持つことができ、すべてがHMRの恩恵を受けます。

使用法

すべての公式スターターキットはデフォルトでHMRを使用するように更新されています。ただし、既存のアプリケーションの場合は、次のようにHMRを設定できます。

開発依存関係としてhot-hook npmパッケージをインストールします。AdonisJSコアチームがこのパッケージを作成しましたが、AdonisJSアプリケーションの外部でも使用できます。

npm i -D hot-hook

次に、以下の設定をpackage.jsonファイルにコピーしてください。boundariesプロパティは、HMRの対象とするグロブパターンの配列を受け入れます。

{
"hotHook": {
"boundaries": [
"./app/controllers/**/*.ts",
"./app/middleware/*.ts"
]
}
}

設定が完了したら、--hmrフラグを使用して開発サーバーを起動できます。

node ace serve --hmr

また、package.jsonファイル内のdevスクリプトをこの新しいフラグを使用するように更新することもできます。

{
"scripts": {
"dev": "node ace serve --hmr"
}
}

フルリロードとHMR

このセクションでは、hot-hookの基本的な動作について説明します。詳細な技術的な理論を読む気分でない場合は、スキップしても構いません 🤓

または、パッケージのREADMEファイルを参照して、さらに詳しい説明を読むこともできます。

完全なリロード(プロセスの再起動)とモジュールのホットリロードがAdonisJSでいつ行われるかを理解しましょう。

依存関係ツリーの作成

--hmrフラグを使用すると、AdonisJSはhot-hookを使用して、bin/server.tsファイルを起点にアプリケーションの依存関係ツリーを作成し、この依存関係ツリーに含まれるすべてのファイルを監視します。

つまり、アプリケーションのソースコードにTypeScriptファイルを作成しても、アプリ内のどこにもインポートされない場合、このファイルはリロードをトリガーしません。ファイルが存在しないかのように無視されます。

境界の識別

次に、hot-hookは設定のboundaries配列を使用して、HMRの対象となるファイルを特定します。

一般的なガイドラインとして、設定ファイル、サービスプロバイダ、プリロードファイルを境界として登録しないでください。これは、これらのファイルが通常、いくつかの副作用を引き起こすためです。以下にいくつかの例を示します。

  • config/database.tsファイルはデータベースとの接続を確立します。このファイルをホットリロードすると、既存の接続が閉じられ、再作成されます。同じことは、追加の複雑さを加えずにプロセス全体を再起動することでも実現できます。

  • start/routes.tsファイルはルートを登録するために使用されます。このファイルをホットリロードすると、フレームワークで登録されている既存のルートが削除され、再登録されます。再起動することは簡単です。

言い換えれば、HTTPリクエスト中にインポート/実行されるモジュールはHMRの境界に含めるべきであり、アプリケーションの起動に必要なモジュールは含めるべきではありません。

リロードの実行

hot-hookが境界を特定した後、境界に属する動的にインポートされたモジュールに対してHMRを実行し、それ以外のファイルに対してはプロセスを再起動します。