Compilation Hooks

The Compilation module is used by the Compiler to create new compilations (or builds). A compilation instance has access to all modules and their dependencies (most of which are circular references). It is the literal compilation of all the modules in the dependency graph of an application. During the compilation phase, modules are loaded, sealed, optimized, chunked, hashed and restored.

The Compilation class also extends Tapable and provides the following lifecycle hooks. They can be tapped the same way as compiler hooks:

compilation.hooks.someHook.tap(/* ... */);

As with the compiler, tapAsync and tapPromise may also be available depending on the type of hook.

buildModule

SyncHook

Triggered before a module build has started, can be used to modify the module.

  • Callback Parameters: module
compilation.hooks.buildModule.tap(
  'SourceMapDevToolModuleOptionsPlugin',
  (module) => {
    module.useSourceMap = true;
  }
);

rebuildModule

SyncHook

Fired before rebuilding a module.

  • Callback Parameters: module

failedModule

SyncHook

Run when a module build has failed.

  • Callback Parameters: module error

succeedModule

SyncHook

Executed when a module has been built successfully.

  • Callback Parameters: module

finishModules

AsyncSeriesHook

Called when all modules have been built without errors.

  • Callback Parameters: modules

finishRebuildingModule

SyncHook

Executed when a module has been rebuilt, in case of both success or with errors.

  • Callback Parameters: module

seal

SyncHook

Fired when the compilation stops accepting new modules.

unseal

SyncHook

Fired when a compilation begins accepting new modules.

optimizeDependencies

SyncBailHook

Fired at the beginning of dependency optimization.

  • Callback Parameters: modules

afterOptimizeDependencies

SyncHook

Fired after the dependency optimization.

  • Callback Parameters: modules

afterChunks

SyncHook

5.83.0+

The afterChunks hook is invoked following the creation of the chunks and module graph, and prior to their optimization. This hook provides an opportunity to examine, analyze, and modify the chunk graph if necessary.

Here's an example of how to utilize the compilation.hooks.afterChunks hook.

  • Callback Parameters: chunks

optimize

SyncHook

Triggered at the beginning of the optimization phase.

optimizeModules

SyncBailHook

Called at the beginning of the module optimization phase. A plugin can tap into this hook to perform optimizations on modules.

  • Callback Parameters: modules

afterOptimizeModules

SyncHook

Called after modules optimization has completed.

  • Callback Parameters: modules

optimizeChunks

SyncBailHook

Called at the beginning of the chunk optimization phase. A plugin can tap into this hook to perform optimizations on chunks.

  • Callback Parameters: chunks

afterOptimizeChunks

SyncHook

Fired after chunk optimization has completed.

  • Callback Parameters: chunks

optimizeTree

AsyncSeriesHook

Called before optimizing the dependency tree. A plugin can tap into this hook to perform a dependency tree optimization.

  • Callback Parameters: chunks modules

afterOptimizeTree

SyncHook

Called after the dependency tree optimization has completed with success.

  • Callback Parameters: chunks modules

optimizeChunkModules

SyncBailHook

Called after the tree optimization, at the beginning of the chunk modules optimization. A plugin can tap into this hook to perform optimizations of chunk modules.

  • Callback Parameters: chunks modules

afterOptimizeChunkModules

SyncHook

Called after the chunkmodules optimization has completed successfully.

  • Callback Parameters: chunks modules

shouldRecord

SyncBailHook

Called to determine whether or not to store records. Returning anything !== false will prevent every other "record" hook from being executed (record, recordModules, recordChunks and recordHash).

reviveModules

SyncHook

Restore module information from records.

  • Callback Parameters: modules records

beforeModuleIds

SyncHook

Executed before assigning an id to each module.

  • Callback Parameters: modules

moduleIds

SyncHook

Called to assign an id to each module.

  • Callback Parameters: modules

optimizeModuleIds

SyncHook

Called at the beginning of the modules id optimization.

  • Callback Parameters: modules

afterOptimizeModuleIds

SyncHook

Called when the modules id optimization phase has completed.

  • Callback Parameters: modules

reviveChunks

SyncHook

Restore chunk information from records.

  • Callback Parameters: chunks records

beforeChunkIds

SyncHook

Executed before assigning an id to each chunk.

  • Callback Parameters: chunks

chunkIds

SyncHook

Called to assign an id to each chunk.

  • Callback Parameters: chunks

optimizeChunkIds

SyncHook

Called at the beginning of the chunks id optimization phase.

  • Callback Parameters: chunks

afterOptimizeChunkIds

SyncHook

Triggered after chunk id optimization has finished.

  • Callback Parameters: chunks

recordModules

SyncHook

Store module info to the records. This is triggered if shouldRecord returns a truthy value.

  • Callback Parameters: modules records

recordChunks

SyncHook

Store chunk info to the records. This is only triggered if shouldRecord returns a truthy value.

  • Callback Parameters: chunks records

beforeModuleHash

SyncHook

Called before modules are hashed.

afterModuleHash

syncHook

Called after modules are hashed.

beforeHash

SyncHook

Called before the compilation is hashed.

afterHash

SyncHook

Called after the compilation is hashed.

recordHash

SyncHook

Store information about record hash to the records. This is only triggered if shouldRecord returns a truthy value.

  • Callback Parameters: records

record

SyncHook

Store information about the compilation to the records. This is only triggered if shouldRecord returns a truthy value.

  • Callback Parameters: compilation records

beforeModuleAssets

SyncHook

Executed before module assets creation.

additionalChunkAssets

SyncHook

Create additional assets for the chunks.

  • Callback Parameters: chunks

shouldGenerateChunkAssets

SyncBailHook

Called to determine whether or not generate chunks assets. Returning anything !== false will allow chunk assets generation.

beforeChunkAssets

SyncHook

Executed before creating the chunks assets.

additionalAssets

AsyncSeriesHook

Create additional assets for the compilation. This hook can be used to download an image, for example:

compilation.hooks.additionalAssets.tapAsync('MyPlugin', (callback) => {
  download('https://img.shields.io/npm/v/webpack.svg', function (resp) {
    if (resp.status === 200) {
      compilation.assets['webpack-version.svg'] = toAsset(resp);
      callback();
    } else {
      callback(
        new Error('[webpack-example-plugin] Unable to download the image')
      );
    }
  });
});

optimizeChunkAssets

AsyncSeriesHook

Optimize any chunk assets. The assets are stored in compilation.assets. A Chunk has a property files which points to all files created by a chunk. Any additional chunk assets are stored in compilation.additionalChunkAssets.

  • Callback Parameters: chunks

Here's an example that adds a banner to each chunk.

compilation.hooks.optimizeChunkAssets.tapAsync(
  'MyPlugin',
  (chunks, callback) => {
    chunks.forEach((chunk) => {
      chunk.files.forEach((file) => {
        compilation.assets[file] = new ConcatSource(
          '/**Sweet Banner**/',
          '\n',
          compilation.assets[file]
        );
      });
    });

    callback();
  }
);

afterOptimizeChunkAssets

SyncHook

The chunk assets have been optimized.

  • Callback Parameters: chunks

Here's an example plugin from @boopathi that outputs exactly what went into each chunk.

compilation.hooks.afterOptimizeChunkAssets.tap('MyPlugin', (chunks) => {
  chunks.forEach((chunk) => {
    console.log({
      id: chunk.id,
      name: chunk.name,
      includes: chunk.getModules().map((module) => module.request),
    });
  });
});

optimizeAssets

AsyncSeriesHook

Optimize all assets stored in compilation.assets.

  • Callback Parameters: assets

afterOptimizeAssets

SyncHook

The assets have been optimized.

  • Callback Parameters: assets

processAssets

AsyncSeriesHook

Asset processing.

Hook parameters:

  • name: string — a name of the plugin
  • stage: Stage — a stage to tap into (see the list of supported stages below)
  • additionalAssets?: true | (assets, [callback]) => (void | Promise<void>) — a callback for additional assets (see below)

Callback parameters:

  • assets: { [pathname: string]: Source } — a plain object, where key is the asset's pathname, and the value is data of the asset represented by the Source.

Example:

compilation.hooks.processAssets.tap(
  {
    name: 'MyPlugin',
    stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS, // see below for more stages
  },
  (assets) => {
    console.log('List of assets and their sizes:');
    Object.entries(assets).forEach(([pathname, source]) => {
      console.log(`${pathname}: ${source.size()} bytes`);
    });
  }
);

Additional assets

In addition to name and stage, you can pass an additionalAssets 5.8.0+ option which accepts either a value of true or a callback function that receives assets as a first argument:

  1. true — run the provided callback again for assets added later by plugins.

    In this mode, the callback will be called multiple times: once for assets added prior to the specified stage, and additional times for assets added by plugins later (on this or next stages).

    compilation.hooks.processAssets.tap(
      {
        name: 'MyPlugin',
        stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
        additionalAssets: true,
      },
      (assets) => {
        // this function will be called multiple times with each bulk of assets
      }
    );
  2. (assets, [callback]) => (void | Promise<void>) — run the specified callback against assets added by plugins later (on this or next stages). The callback must respect the type of the tap method used (e.g. when used with tapPromise(), it should return a promise).

    compilation.hooks.processAssets.tap(
      {
        name: 'MyPlugin',
        stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
        additionalAssets: (assets) => {
          // this function potentially could be called multiple times for assets added on later stages
        },
      },
      (assets) => {
        // this function will be called once with assets added by plugins on prior stages
      }
    );

List of asset processing stages

Here's a list of supported stages (in the order of processing):

  • PROCESS_ASSETS_STAGE_ADDITIONAL — add additional assets to the compilation.
  • PROCESS_ASSETS_STAGE_PRE_PROCESS — basic preprocessing of the assets.
  • PROCESS_ASSETS_STAGE_DERIVED — derive new assets from the existing assets.
  • PROCESS_ASSETS_STAGE_ADDITIONS — add additional sections to the existing assets e.g. banner or initialization code.
  • PROCESS_ASSETS_STAGE_OPTIMIZE — optimize existing assets in a general way.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT — optimize the count of existing assets, e.g. by merging them.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY — optimize the compatibility of existing assets, e.g. add polyfills or vendor prefixes.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE — optimize the size of existing assets, e.g. by minimizing or omitting whitespace.
  • PROCESS_ASSETS_STAGE_DEV_TOOLING — add development tooling to the assets, e.g. by extracting a source map.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE 5.8.0+ — optimize the numbers of existing assets, e.g. by inlining assets into other assets.
  • PROCESS_ASSETS_STAGE_SUMMARIZE — summarize the list of existing assets.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_HASH — optimize the hashes of the assets, e.g. by generating real hashes of the asset content.
  • PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER — optimize the transfer of existing assets, e.g. by preparing a compressed (gzip) file as separate asset.
  • PROCESS_ASSETS_STAGE_ANALYSE — analyze the existing assets.
  • PROCESS_ASSETS_STAGE_REPORT — creating assets for the reporting purposes.

Assets info

The "asset info" metadata is not automatically provided for this hook. If needed, you will have to resolve this metadata manually using the compilation instance and the provided asset pathname. This will be improved in a future version of the webpack.

Example:

compilation.hooks.processAssets.tap(
  {
    /** … */
  },
  (assets) => {
    Object.entries(assets).forEach(([pathname, source]) => {
      const assetInfo = compilation.assetsInfo.get(pathname);
      // @todo: do something with "pathname", "source" and "assetInfo"
    });
  }
);

afterProcessAssets

SyncHook

Called after the processAssets hook had finished without error.

needAdditionalSeal

SyncBailHook

Called to determine if the compilation needs to be unsealed to include other files.

afterSeal

AsyncSeriesHook

Executed right after needAdditionalSeal.

chunkHash

SyncHook

Triggered to emit the hash for each chunk.

  • Callback Parameters: chunk chunkHash

moduleAsset

SyncHook

Called when an asset from a module was added to the compilation.

  • Callback Parameters: module filename

chunkAsset

SyncHook

Triggered when an asset from a chunk was added to the compilation.

  • Callback Parameters: chunk filename

assetPath

SyncWaterfallHook

Called to determine the path of an asset.

  • Callback Parameters: path options

needAdditionalPass

SyncBailHook

Called to determine if an asset needs to be processed further after being emitted.

childCompiler

SyncHook

Executed after setting up a child compiler.

  • Callback Parameters: childCompiler compilerName compilerIndex

normalModuleLoader

Since webpack v5 normalModuleLoader hook was removed. Now to access the loader use NormalModule.getCompilationHooks(compilation).loader instead.

9 Contributors

slavafominbyzykmadhavarshneymisterdevwizardofhogwartsEugeneHlushkochenxsanjamesgeorge007snitin315