回答:
ローダーは、require("my-loader!./my-awesome-module")
コードのようにsthを使用すると、実質的にすべてのファイル形式の前処理変換を実行します。プラグインと比較すると、(a)単一の関数のみをwebpackに公開し、(b)実際のビルドプロセスに影響を与えることができないため、プラグインは非常に単純です。
一方、プラグインは、webpacksビルドシステム内のフックを登録し、コンパイラーにアクセス(および変更)し、コンパイル方法と同様に機能するため、webpackに深く統合できます。したがって、それらはより強力ですが、保守も困難です。
補足的で単純な答えを追加します。
ローダー:
ローダーは、バンドルの生成中または生成前に、個々のファイルレベルで動作します。
プラグイン:
プラグインはバンドルまたはチャンクレベルで動作し、通常はバンドル生成プロセスの最後に動作します。プラグインは、バンドル自体の作成方法も変更できます。プラグインはローダーよりも強力なコントロールを備えています。
ちょうど例として、ローダーが動作している場所とプラグインが動作している場所を下の画像ではっきりと見ることができます-
基本的に、webpackは単なるファイルバンドルです。非常に単純なシナリオ(コード分割なし)を考えると、これは次のアクション(高レベル)だけを意味する可能性があります。
上記の手順を詳しく調べると、これはJavaコンパイラー(または任意のコンパイラー)の動作と共鳴します。もちろん違いはありますが、ローダーやプラグインを理解するのにそれらは重要ではありません。
ローダー:
これは、webpackがすべてのファイルタイプをバンドルすることを約束しているためです。
コアでのwebpackはjsファイルをバンドルするのに十分な能力しかないため、この約束は、webpackが使用できる方法で外部コードが特定のファイルタイプを変換できるビルドフローをwebpackコアチームに組み込む必要があることを意味しました。
これらの外部コードはローダーと呼ばれ、通常、上記のステップ1と3で実行されます。したがって、これらのローダーを実行する必要がある段階は明らかであるため、フックは不要であり、ビルドプロセスにも影響を与えません(ビルドまたはバンドルはステップ4でのみ発生するため)。
したがって、ローダーはコンパイルの段階を準備し、Webpackコンパイラーの柔軟性を拡張します。
プラグイン:
これは、webpackが変数の出力を直接約束しない場合でも、世界中がそれを望んでおり、webpackが許可しているためです。
中核となるwebpackは単なるバンドラーであり、そのためにいくつかのステップとサブステップを実行するため、これらのステップを利用して追加の機能を組み込むことができます。
たとえば、webpackコンパイラのネイティブ機能であるプロダクションビルドプロセス(縮小およびファイルシステムへの書き込み)は、コア機能(単なるバンドル)の拡張機能として扱うことができ、ネイティブプラグインのように扱うことができます。彼らがそれを提供しなかったら、誰か他の人がそれをしたでしょう。
上記のネイティブプラグインを見ると、Webpackのバンドルまたはコンパイルをコアバンドリングプロセスに加えて、オフにしたり、カスタマイズまたは拡張したりできる多くのネイティブプラグインプロセスに分解できるように見えます。これは、外部コードが選択できる特定のポイント(フックと呼ばれる)でバンドルプロセスに参加できるようにすることを意味しました。
したがって、プラグインは出力に影響を与え、Webpackコンパイラの機能を拡張します。