compilation 钩子

Compilation 模块会被 Compiler 用来创建新的 compilation 对象(或新的 build 对象)。 compilation 实例能够访问所有的模块和它们的依赖(大部分是循环依赖)。 它会对应用程序的依赖图中所有模块, 进行字面上的编译(literal compilation)。 在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)。

Compilation 类扩展(extend)自 Tapable,并提供了以下生命周期钩子。 可以按照 compiler 钩子的相同方式来调用 tap:

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

compiler 用法相同,取决于不同的钩子类型, 所以也可以在某些钩子上访问 tapAsynctapPromise

buildModule

SyncHook

在模块构建开始之前触发,可以用来修改模块。

  • 回调参数:module
compilation.hooks.buildModule.tap(
  'SourceMapDevToolModuleOptionsPlugin',
  (module) => {
    module.useSourceMap = true;
  }
);

rebuildModule

SyncHook

在重新构建一个模块之前触发。

  • 回调参数:module

failedModule

SyncHook

模块构建失败时执行。

  • 回调参数:module error

succeedModule

SyncHook

模块构建成功时执行。

  • 回调参数:module

finishModules

AsyncSeriesHook

所有模块都完成构建并且没有错误时执行。

  • 回调参数:modules

finishRebuildingModule

SyncHook

一个模块完成重新构建时执行,在都成功或有错误的情况下。

  • 回调参数:module

seal

SyncHook

compilation 对象停止接收新的模块时触发。

unseal

SyncHook

compilation 对象开始接收新模块时触发。

optimizeDependencies

SyncBailHook

依赖优化开始时触发。

  • 回调参数:modules

afterOptimizeDependencies

SyncHook

依赖优化之后触发。

  • 回调参数:modules

optimize

SyncHook

优化阶段开始时触发。

optimizeModules

SyncBailHook

在模块优化阶段开始时调用。插件可以 tap 此钩子对模块进行优化。

  • 回调参数:modules

afterOptimizeModules

SyncHook

在模块优化完成之后调用。

  • 回调参数:modules

optimizeChunks

SyncBailHook

在 chunk 优化阶段开始时调用。插件可以 tap 此钩子对 chunk 执行优化。

  • 回调参数:chunks

afterOptimizeChunks

SyncHook

chunk 优化完成之后触发。

  • 回调参数:chunks

optimizeTree

AsyncSeriesHook

在优化依赖树之前调用。插件可以 tap 此钩子执行依赖树优化。

  • 回调参数:chunks modules

afterOptimizeTree

SyncHook

在依赖树优化成功完成之后调用。

  • 回调参数:chunks modules

optimizeChunkModules

SyncBailHook

在树优化之后,chunk 模块优化开始时调用。插件可以 tap 此钩子来执行 chunk 模块的优化。

  • 回调参数:chunks modules

afterOptimizeChunkModules

SyncHook

在 chunk 模块优化成功完成之后调用。

  • 回调参数:chunks modules

shouldRecord

SyncBailHook

调用来决定是否存储 record。返回任何内容 !== false 将阻止执行所有其他 "record" 钩子(record, recordModules, recordChunksrecordHash)。

reviveModules

SyncHook

从 record 中恢复模块信息。

  • 回调参数:modules records

beforeModuleIds

SyncHook

在为每个模块分配 id 之前执行。

  • 回调参数:modules

moduleIds

SyncHook

调用来每个模块分配一个 id

  • 回调参数:modules

optimizeModuleIds

SyncHook

在模块 id 优化开始时调用。

  • 回调参数:modules

afterOptimizeModuleIds

SyncHook

在模块 id 优化完成时调用。

  • 回调参数:modules

reviveChunks

SyncHook

从 record 中恢复 chunk 信息。

  • 回调参数:chunks records

beforeChunkIds

SyncHook

在为每个 chunk 分配 id 之前执行。

  • 回调参数:chunks

chunkIds

SyncHook

调用时,会为每个 chunk 分配一个 id

  • 回调函数的参数为:chunks

optimizeChunkIds

SyncHook

在 chunk id 优化阶段开始时调用。

  • 回调参数:chunks

afterOptimizeChunkIds

SyncHook

chunk id 优化结束之后触发。

  • 回调参数:chunks

recordModules

SyncHook

将模块信息存储到 record 中。shouldRecord 返回 truthy 值时触发。

  • 回调参数:modules records

recordChunks

SyncHook

将 chunk 存储到 record 中。shouldRecord 返回 truthy 值时触发。

  • 回调参数:chunks records

beforeModuleHash

SyncHook

在创建模块哈希(hash)之前。

afterModuleHash

syncHook

在创建模块哈希(hash)之后。

beforeHash

SyncHook

在 compilation 添加哈希(hash)之前。

afterHash

SyncHook

在 compilation 添加哈希(hash)之后。

recordHash

SyncHook

将有关 record 的信息存储到 records 中。仅在 shouldRecord 返回 truthy 值时触发。

  • 回调参数:records

record

SyncHook

compilation 相关信息存储到 record 中。仅在 shouldRecord 返回 truthy 值时触发。

  • 回调参数:compilation records

beforeModuleAssets

SyncHook

在创建模块 asset 之前执行。

additionalChunkAssets

SyncHook

为这些 chunk 创建其他 asset。

  • 回调参数:chunks

shouldGenerateChunkAssets

SyncBailHook

调用以确定是否生成 chunk asset。返回任何 !== false 将允许生成 chunk asset。

beforeChunkAssets

SyncHook

在创建 chunk asset 之前。

additionalAssets

AsyncSeriesHook

为 compilation 创建额外 asset。 这个钩子可以用来下载图像,例如:

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

优化所有 chunk asset。asset 存储在 compilation.assets 中。 每个 Chunk 都具有一个 files 属性,其指向由一个 chunk 创建的所有文件。 任何额外 chunk asset 都存储在 compilation.additionalChunkAssets 中。

  • 回调参数: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

chunk asset 已经被优化。

  • 回调参数:chunks

这里是一个来自 @boopathi 的示例插件,详细地输出每个 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

优化存储在 compilation.assets 中的所有 asset。

  • 回调参数:assets

afterOptimizeAssets

SyncHook

asset 已经优化。

  • 回调参数:assets

processAssets

AsyncSeriesHook

asset 处理.

Hook 参数:

  • name: string — 插件名称
  • 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)

回调参数:

  • assets: { [pathname: string]: Source } — 普通对象,其中 key 是 asset 的路径名,value 是 asset 的数据,具体的代表请参考 Source

示例:

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`);
    });
  }
);

额外的 assets

除了 namestage 以外,你还可以传递 additionalAssets 5.8.0+ 选项,此选项可接受 true 或者一个带有 assets 的函数作为参数:

  1. true - 针对插件后续添加的 asset 执行回调。

    在此模式下,回调将被多次调用:一次是在指定阶段之前添加资产时,另一次是后来由插件添加资产时。(在本阶段或下一阶段)。

    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>) - 针对插件后续添加的 asset 执行指定的回调(在本阶段或下一阶段)。回调必须遵循所使用的 tap 函数的类型(例如,当与 tapPromise() 一同使用时,它应该返回一个 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
      }
    );

资产处理 stage 的列表

如下是我们可以使用的 stage 清单(按顺序处理):

  • PROCESS_ASSETS_STAGE_ADDITIONAL — 在编译中添加额外的 asset。
  • PROCESS_ASSETS_STAGE_PRE_PROCESS — asset 进行了基础预处理。
  • PROCESS_ASSETS_STAGE_DERIVED — 从已有 asset 中获取新的 asset。
  • PROCESS_ASSETS_STAGE_ADDITIONS — 为现有的 asset 添加额外的内容,例如 banner 或初始代码。
  • PROCESS_ASSETS_STAGE_OPTIMIZE — 以通用的方式优化已有 asset。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT — 优化现有资产的数量,例如,进行合并操作。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY — 优化现有 asset 兼容性,例如添加 polyfills 或者 vendor prefixes。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE — 优化现有 asset 大小,例如进行压缩或者删除空格。
  • PROCESS_ASSETS_STAGE_DEV_TOOLING — 为 asset 添加开发者工具,例如,提取 source map。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE 5.8.0+ — 优化已有 asset 数量,例如,通过将 asset 内联到其他 asset 中。
  • PROCESS_ASSETS_STAGE_SUMMARIZE — 整理现有 asset 列表。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_HASH — 优化 asset 的 hash 值,例如,生成 asset 内容的真实 hash 值。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER — 优化已有 asset 的转换操作,例如对 asset 进行压缩,并作为独立的 asset。
  • PROCESS_ASSETS_STAGE_ANALYSE — 分析已有 asset。
  • PROCESS_ASSETS_STAGE_REPORT — 创建用于上报的 asset。

Assets info

"asset info" 元数据不会自动提供给这个 hook。如果必须使用,你需要通过编译实例以及 asset 路径来手动获取这个元数据。这将在未来的 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

processAssets hook 无错误执行后调用。

needAdditionalSeal

SyncBailHook

调用来决定 compilation 是否需要解除 seal 以引入其他文件。

afterSeal

AsyncSeriesHook

needAdditionalSeal 之后立即执行。

chunkHash

SyncHook

触发来为每个 chunk 生成 hash。

  • 回调参数:chunk chunkHash

moduleAsset

SyncHook

一个模块中的一个 asset 被添加到 compilation 时调用。

  • 回调参数:module filename

chunkAsset

SyncHook

一个 chunk 中的一个 asset 被添加到 compilation 时调用。

  • 回调参数:chunk filename

assetPath

SyncWaterfallHook

调用以决定 asset 的路径。

  • 回调参数:path options

needAdditionalPass

SyncBailHook

调用以决定 asset 在输出后是否需要进一步处理。

childCompiler

SyncHook

子 compiler 设置之后执行。

  • 回调参数:childCompiler compilerName compilerIndex

normalModuleLoader

从 webpack v5 开始,normalModuleLoader 钩子已经删除。现在要访问 loader 请改用 NormalModule.getCompilationHooks(compilation).loader

8 位贡献者

slavafominbyzykmadhavarshneymisterdevwizardofhogwartsEugeneHlushkochenxsanjamesgeorge007