プラグインAPI

プラグインは webpack エコシステムの重要な要素であり、コミュニティが webpack のコンパイルプロセスを活用するための強力な方法を提供します。プラグインは、コンパイル全体で発生する主要なイベントにフックできます。どの段階でも、プラグインはcompilerと、該当する場合は現在のcompilationに完全にアクセスできます。

webpack のプラグインインターフェイスのバックボーンを提供するtapableユーティリティから始めましょう。

Tapable

この小さなライブラリは webpack のコアユーティリティですが、同様のプラグインインターフェイスを提供するために他の場所でも使用できます。webpack の多くのオブジェクトはTapableクラスを拡張しています。このクラスは、プラグインがコンパイル中に実行されるカスタムビルドステップを注入するために使用できるtaptapAsync、およびtapPromiseメソッドを公開します。

詳細については、ドキュメントを参照してください。3つのtapメソッドと、それらを提供するフックの理解が不可欠です。Tapableを拡張するオブジェクト(例:コンパイラ)、それらが提供するフック、および各フックの型(例:SyncHook)が記載されます。

プラグインの種類

使用されるフックと適用されるtapメソッドに応じて、プラグインはさまざまな方法で機能します。この仕組みは、Tapableによって提供されるフックと密接に関連しています。コンパイラフックはそれぞれ、利用可能なtapメソッドを示す基になるTapableフックを記述しています。

したがって、どのイベントにtapするかによって、プラグインの動作が異なる場合があります。たとえば、compileステージにフックする場合は、同期のtapメソッドのみを使用できます

compiler.hooks.compile.tap('MyPlugin', (params) => {
  console.log('Synchronously tapping the compile hook.');
});

ただし、AsyncHookを利用するrunの場合、tapAsyncまたはtapPromise(およびtap)を利用できます

compiler.hooks.run.tapAsync(
  'MyPlugin',
  (source, target, routesList, callback) => {
    console.log('Asynchronously tapping the run hook.');
    callback();
  }
);

compiler.hooks.run.tapPromise('MyPlugin', (source, target, routesList) => {
  return new Promise((resolve) => setTimeout(resolve, 1000)).then(() => {
    console.log('Asynchronously tapping the run hook with a delay.');
  });
});

compiler.hooks.run.tapPromise(
  'MyPlugin',
  async (source, target, routesList) => {
    await new Promise((resolve) => setTimeout(resolve, 1000));
    console.log('Asynchronously tapping the run hook with a delay.');
  }
);

結論として、compilerhookするためのさまざまな方法があり、それぞれがプラグインが適切と判断したとおりに実行できます。

カスタムフック

他のプラグインがtapできるコンパイルにカスタムフックを提供するには、次のことを行う必要があります。

  1. コンパイルフック用のモジュールスコープのWeakMapを作成します

    const compilationHooks = new WeakMap<Compilation, MyHooks>();
    
    interface MyHooks {
      custom: SyncHook<[number, string]>;
    }
  2. プラグインに静的メソッドを作成します

    static getCompilationHooks(compilation: Compilation) : MyHooks {
      let hooks = compilationHooks.get(compilation);
      if(hooks === undefined) {
        compilationHooks.set(compilation, hooks = {
          custom: new SyncHook()
        });
      }
      return hooks;
    }
  3. プラグインで以下のようにフックを呼び出します

    const hooks = MyPlugin.getCompilationHooks(compilation);
    
    hooks.custom.call(1, 'hello');
  4. 他のプラグインもカスタムフックにアクセスできます

    import MyPlugin from 'my-plugin';
    
    const hooks = MyPlugin.getCompilationHooks(compilation);
    
    hooks.custom.tap('OtherPlugin', (n, s) => {
      // magic
    });

繰り返しになりますが、さまざまなフッククラスとその仕組みの詳細については、tapableドキュメントを参照してください。

進捗状況の報告

プラグインは、デフォルトで進捗メッセージを stderr に出力するProgressPluginを介して進捗状況を報告できます。進捗状況の報告を有効にするには、webpack CLIの実行時に--progress引数を渡します。

ProgressPluginreportProgress関数に異なる引数を渡すことで、出力される内容をカスタマイズできます。

進捗状況を報告するには、プラグインはcontext: trueオプションを使用してフックにtapする必要があります

compiler.hooks.emit.tapAsync(
  {
    name: 'MyPlugin',
    context: true,
  },
  (context, compiler, callback) => {
    const reportProgress = context && context.reportProgress;
    if (reportProgress) reportProgress(0.95, 'Starting work');
    setTimeout(() => {
      if (reportProgress) reportProgress(0.95, 'Done work');
      callback();
    }, 1000);
  }
);

reportProgress関数は、次の引数で呼び出すことができます。

reportProgress(percentage, ...args);
  • percentage:この引数は未使用です。代わりに、ProgressPluginは、現在のフックに基づいてパーセンテージを計算します。
  • ...args:任意の数の文字列。これらは、ユーザーに報告されるProgressPluginハンドラーに渡されます。

コンパイラフックおよびコンパイルフックのサブセットのみがreportProgress関数をサポートすることに注意してください。完全なリストについては、ProgressPluginを参照してください。

ロギング

ロギングAPIは webpack 4.37のリリース以降利用可能です。stats 設定loggingが有効になっている場合や、インフラストラクチャロギングが有効になっている場合、プラグインはメッセージをログに記録できます。これは、それぞれのロガー形式(統計、インフラストラクチャ)で出力されます。

  • プラグインは、ロギングにcompilation.getLogger('PluginName')を使用することを推奨します。この種のロギングは統計に保存され、それに応じてフォーマットされます。ユーザーはこれをフィルタリングしてエクスポートできます。
  • プラグインは、ロギングにcompiler.getInfrastructureLogger('PluginName')を使用できます。infrastructureロギングの使用は統計に保存されないため、フォーマットされません。通常、コンソール/ダッシュボード/GUIに直接ログが記録されます。ユーザーはこれをフィルタリングできます。
  • プラグインは、ロギングサポートを検出するための特定のフォールバックロジックcompilation.getLogger ? compilation.getLogger('PluginName') : consoleを使用して、compilationオブジェクトでgetLoggerメソッドをサポートしない古い webpack バージョンが使用されている場合のフォールバックを提供できます。

次のステップ

利用可能なすべてのcompilerフックと、それらが利用可能にするパラメーターの詳細なリストについては、コンパイラフックセクションを参照してください。

7 貢献者

thelarkinnpksjcee-cloudbyzykEugeneHlushkowizardofhogwartssnitin315