プラグインパターン

プラグインは、webpackビルドシステム内でカスタマイズを実行するための無限の可能性を提供します。これにより、カスタムアセットタイプを作成したり、独自のビルド変更を実行したり、ミドルウェアを使用してwebpackランタイムを強化したりできます。プラグインの作成中に役立つwebpackの機能を以下に示します。

アセット、チャンク、モジュール、依存関係の調査

コンパイルが完了すると、コンパイル内のすべての構造をトラバースできます。

class MyPlugin {
  apply(compiler) {
    compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
      // Explore each chunk (build output):
      compilation.chunks.forEach((chunk) => {
        // Explore each module within the chunk (built inputs):
        chunk.getModules().forEach((module) => {
          // Explore each source file path that was included into the module:
          module.buildInfo &&
            module.buildInfo.fileDependencies &&
            module.buildInfo.fileDependencies.forEach((filepath) => {
              // we've learned a lot about the source structure now...
            });
        });

        // Explore each asset filename generated by the chunk:
        chunk.files.forEach((filename) => {
          // Get the asset source for each file generated by the chunk:
          var source = compilation.assets[filename].source();
        });
      });

      callback();
    });
  }
}
module.exports = MyPlugin;
  • compilation.modules: コンパイル内のモジュール(ビルド入力)のセット。各モジュールは、ソースライブラリから生ファイルのビルドを管理します。
  • module.fileDependencies: モジュールに含まれるソースファイルパスの配列。これには、ソースJavaScriptファイル自体(例:index.js)と、それが要求したすべての依存アセットファイル(スタイルシート、画像など)が含まれます。依存関係を確認すると、モジュールに属するソースファイルを確認するのに役立ちます。
  • compilation.chunks: コンパイル内のチャンク(ビルド出力)のセット。各チャンクは、最終的にレンダリングされたアセットの構成を管理します。
  • chunk.getModules(): チャンクに含まれるモジュールの配列。拡張機能として、各モジュールの依存関係を確認して、チャンクに供給された生のソースファイルを確認できます。
  • chunk.files: チャンクによって生成された出力ファイル名のセット。これらのアセットソースには、compilation.assetsテーブルからアクセスできます。

ウォッチグラフの監視

webpackミドルウェアを実行している間、各コンパイルにはfileDependencies Set(監視対象のファイル)と、監視対象のファイルパスをタイムスタンプにマッピングするfileTimestamps Mapが含まれます。これらは、コンパイル内でどのファイルが変更されたかを検出するのに非常に役立ちます。

class MyPlugin {
  constructor() {
    this.startTime = Date.now();
    this.prevTimestamps = new Map();
  }
  apply(compiler) {
    compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
      const changedFiles = Array.from(compilation.fileTimestamps.keys()).filter(
        (watchfile) => {
          return (
            (this.prevTimestamps.get(watchfile) || this.startTime) <
            (compilation.fileTimestamps.get(watchfile) || Infinity)
          );
        }
      );

      this.prevTimestamps = compilation.fileTimestamps;
      callback();
    });
  }
}

module.exports = MyPlugin;

また、新しいファイルパスをウォッチグラフに供給して、それらのファイルが変更されたときにコンパイルトリガーを受け取ることもできます。有効なファイルパスをcompilation.fileDependencies Setに追加して、監視対象ファイルに追加します。

変更されたチャンク

ウォッチグラフと同様に、ハッシュを追跡することで、コンパイル内で変更されたチャンク(またはモジュール)を監視できます。

class MyPlugin {
  constructor() {
    this.chunkVersions = {};
  }
  apply(compiler) {
    compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
      var changedChunks = compilation.chunks.filter((chunk) => {
        var oldVersion = this.chunkVersions[chunk.name];
        this.chunkVersions[chunk.name] = chunk.hash;
        return chunk.hash !== oldVersion;
      });
      callback();
    });
  }
}

module.exports = MyPlugin;

3 コントリビューター

nveenjainEugeneHlushkobenglynn