Как использовать contentHash в собственном плагине?

Webpack предоставляет мощные возможности для управления и оптимизации бандлов JavaScript, CSS и других ресурсов. Одной из таких возможностей является использование contentHash для генерации уникальных идентификаторов файлов на основе их содержимого. В этом ответе я расскажу о том, как использовать contentHash в своем собственном плагине для Webpack.

contentHash является одним из шаблонных параметров в Webpack, который можно использовать версиями файлов или имени выходного файла. Он генерируется на основе содержимого файла, и если содержимое меняется, contentHash также меняется. Это очень полезно для кеширования статических ресурсов, чтобы обновлять их только при изменении.

Для использования contentHash в собственном плагине вам потребуется выполнить следующие шаги:

1. Создайте свой собственный плагин, расширяющий класс webpack.Plugin. Например:

class MyCustomPlugin extends webpack.Plugin {
  constructor(options) {
    super();
    this.options = options;
  }

  apply(compiler) {
    compiler.hooks.emit.tapAsync('MyCustomPlugin', (compilation, callback) => {
      // Ваш код
      callback();
    });
  }
}

2. В вашем плагине, в методе apply, прикрепите обработчик к emit хуку компилятора. emit вызывается после того, как Webpack сгенерирует бандлы, но перед тем, как они будут записаны на диск.

3. В обработчике emit получите информацию о всех сгенерированных файлах, используя compilation.assets. Например, чтобы получить имена всех сгенерированных CSS файлов, можно выполнить следующий код:

const cssFiles = Object.keys(compilation.assets).filter(assetName => assetName.endsWith('.css'));

4. Для каждого файла, на который вы хотите применить contentHash, используйте метод compilation.getAssetSource для получения содержимого файла, а затем вычислите contentHash для этого содержимого. Например:

const fileContent = compilation.getAssetSource(assetName);
const contentHash = crypto.createHash('md5').update(fileContent).digest("hex");

5. Используйте полученный contentHash, чтобы обновить имя файла или добавить его в другое место в вашем плагине. Например, вы можете добавить хеш в имя файла следующим образом:

const hashedFileName = assetName.replace(/(.[^.]+)$/, `.[${contentHash}]$1`);

6. При необходимости, обновите содержимое файла, используя метод compilation.assets[assetName].source. Например, чтобы обновить содержимое CSS файла с хешем в его имени:

compilation.assets[hashedFileName] = {
  source: () => fileContent,
  size: () => fileContent.length,
};

7. Наконец, удалите старый файл, если это необходимо:

`javascript
dele