Compilation 钩子

Compilation 模块由 Compiler 用于创建新的编译(或构建)。compilation 实例可以访问所有模块及其依赖项(其中大部分是循环引用)。它是应用程序依赖图中所有模块的字面编译。在编译阶段,模块被加载、封装、优化、分块、哈希和恢复。

Compilation 类也扩展了 Tapable 并提供了以下生命周期钩子。它们可以像编译器钩子一样被监听。

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

与编译器一样,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

当编译停止接受新模块时触发。

unseal

SyncHook

当编译开始接受新模块时触发。

optimizeDependencies

SyncBailHook

在依赖优化开始时触发。

  • 回调参数:modules

afterOptimizeDependencies

SyncHook

在依赖优化之后触发。

  • 回调参数:modules

afterChunks

SyncHook

5.83.0+

afterChunks 钩子在分块和模块图创建之后、优化之前调用。此钩子提供了在必要时检查、分析和修改分块图的机会。

这里是关于如何使用 compilation.hooks.afterChunks 钩子的一个示例

  • 回调参数:chunks

optimize

SyncHook

在优化阶段开始时触发。

optimizeModules

SyncBailHook

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

  • 回调参数:modules

afterOptimizeModules

SyncHook

模块优化完成后调用。

  • 回调参数:modules

optimizeChunks

SyncBailHook

在分块优化阶段开始时调用。插件可以监听此钩子以对分块执行优化。

  • 回调参数:chunks

afterOptimizeChunks

SyncHook

分块优化完成后触发。

  • 回调参数:chunks

optimizeTree

AsyncSeriesHook

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

  • 回调参数:chunks modules

afterOptimizeTree

SyncHook

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

  • 回调参数:chunks modules

optimizeChunkModules

SyncBailHook

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

  • 回调参数:chunks modules

afterOptimizeChunkModules

SyncHook

分块模块优化成功完成后调用。

  • 回调参数:chunks modules

shouldRecord

SyncBailHook

调用此钩子以确定是否存储记录。返回任何 !== false 的值将阻止其他所有“记录”钩子(recordrecordModulesrecordChunksrecordHash)的执行。

reviveModules

SyncHook

从记录中恢复模块信息。

  • 回调参数:modules records

beforeModuleIds

SyncHook

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

  • 回调参数:modules

moduleIds

SyncHook

调用此钩子为每个模块分配 id

  • 回调参数:modules

optimizeModuleIds

SyncHook

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

  • 回调参数:modules

afterOptimizeModuleIds

SyncHook

模块 id 优化阶段完成后调用。

  • 回调参数:modules

reviveChunks

SyncHook

从记录中恢复分块信息。

  • 回调参数:chunks records

beforeChunkIds

SyncHook

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

  • 回调参数:chunks

chunkIds

SyncHook

调用此钩子为每个分块分配 id

  • 回调参数:chunks

optimizeChunkIds

SyncHook

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

  • 回调参数:chunks

afterOptimizeChunkIds

SyncHook

分块 id 优化完成后触发。

  • 回调参数:chunks

recordModules

SyncHook

将模块信息存储到记录中。如果 shouldRecord 返回一个真值,则会触发此钩子。

  • 回调参数:modules records

recordChunks

SyncHook

将分块信息存储到记录中。仅当 shouldRecord 返回一个真值时才会触发此钩子。

  • 回调参数:chunks records

beforeModuleHash

SyncHook

在模块哈希之前调用。

afterModuleHash

syncHook

在模块哈希之后调用。

beforeHash

SyncHook

在编译哈希之前调用。

afterHash

SyncHook

在编译哈希之后调用。

recordHash

SyncHook

将记录哈希信息存储到 records 中。仅当 shouldRecord 返回一个真值时才会触发此钩子。

  • 回调参数:records

record

SyncHook

compilation 的信息存储到 records 中。仅当 shouldRecord 返回一个真值时才会触发此钩子。

  • 回调参数:compilation records

beforeModuleAssets

SyncHook

在模块资产创建之前执行。

additionalChunkAssets

SyncHook

为分块创建额外的资产。

  • 回调参数:chunks

shouldGenerateChunkAssets

SyncBailHook

调用此钩子以确定是否生成分块资产。返回任何 !== false 的值将允许生成分块资产。

beforeChunkAssets

SyncHook

在创建分块资产之前执行。

additionalAssets

AsyncSeriesHook

为编译创建额外的资产。例如,此钩子可用于下载图片。

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

优化任何分块资产。资产存储在 compilation.assets 中。一个 Chunk 有一个 files 属性,指向由分块创建的所有文件。任何额外的分块资产都存储在 compilation.additionalChunkAssets 中。

  • 回调参数:chunks

这里是一个为每个分块添加横幅的示例。

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

分块资产已优化。

  • 回调参数:chunks

这里是来自 @boopathi 的一个插件示例,它精确地输出了每个分块中的内容。

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 中的所有资产。

  • 回调参数:assets

afterOptimizeAssets

SyncHook

资产已优化。

  • 回调参数:assets

processAssets

AsyncSeriesHook

资产处理。

钩子参数

  • name: string — 插件的名称
  • stage: Stage — 要监听的阶段(参见下方支持的阶段列表
  • additionalAssets?: true | (assets, [callback]) => (void | Promise<void>) — 用于额外资产的回调(见下方

回调参数

  • assets: { [pathname: string]: Source } — 一个普通对象,其中键是资产的路径名,值是由 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`);
    });
  }
);

额外资产

除了 namestage,你还可以传递一个 additionalAssets 5.8.0+ 选项,它接受 true 值或一个接收 assets 作为第一个参数的回调函数。

  1. true — 对插件后续添加的资产再次运行提供的回调。

    在此模式下,回调将被多次调用:一次用于在指定阶段之前添加的资产,多次用于插件后续添加的资产(在此阶段或下一阶段)。

    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>) — 对插件后续添加的资产(在此阶段或下一阶段)运行指定的回调。回调必须符合所使用的 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
      }
    );

资产处理阶段列表

以下是支持的阶段列表(按处理顺序):

  • PROCESS_ASSETS_STAGE_ADDITIONAL — 向编译中添加额外资产。
  • PROCESS_ASSETS_STAGE_PRE_PROCESS — 资产的基本预处理。
  • PROCESS_ASSETS_STAGE_DERIVED — 从现有资产派生新资产。
  • PROCESS_ASSETS_STAGE_ADDITIONS — 向现有资产添加额外部分,例如横幅或初始化代码。
  • PROCESS_ASSETS_STAGE_OPTIMIZE — 以通用方式优化现有资产。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT — 优化现有资产的数量,例如通过合并它们。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY — 优化现有资产的兼容性,例如添加 polyfills 或厂商前缀。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE — 优化现有资产的大小,例如通过最小化或省略空白。
  • PROCESS_ASSETS_STAGE_DEV_TOOLING — 向资产添加开发工具,例如通过提取源映射。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE 5.8.0+ — 优化现有资产的数量,例如通过将资产内联到其他资产中。
  • PROCESS_ASSETS_STAGE_SUMMARIZE — 总结现有资产列表。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_HASH — 优化资产的哈希,例如通过生成资产内容的真实哈希。
  • PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER — 优化现有资产的传输,例如通过将压缩(gzip)文件准备为单独的资产。
  • PROCESS_ASSETS_STAGE_ANALYSE — 分析现有资产。
  • PROCESS_ASSETS_STAGE_REPORT — 为报告目的创建资产。

资产信息

此钩子不会自动提供“资产信息”元数据。如果需要,你必须使用编译实例和提供的资产路径名手动解析此元数据。这将在 webpack 的未来版本中得到改进。

示例

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 钩子无错误完成后调用。

needAdditionalSeal

SyncBailHook

调用此钩子以确定编译是否需要解除封装以包含其他文件。

afterSeal

AsyncSeriesHook

needAdditionalSeal 之后立即执行。

chunkHash

SyncHook

触发以发出每个分块的哈希。

  • 回调参数:chunk chunkHash

moduleAsset

SyncHook

当模块中的资产添加到编译时调用。

  • 回调参数:module filename

chunkAsset

SyncHook

当分块中的资产添加到编译时触发。

  • 回调参数:chunk filename

assetPath

SyncWaterfallHook

调用此钩子以确定资产的路径。

  • 回调参数:path options

needAdditionalPass

SyncBailHook

调用此钩子以确定资产在发出后是否需要进一步处理。

childCompiler

SyncHook

设置子编译器后执行。

  • 回调参数:childCompiler compilerName compilerIndex

normalModuleLoader

自 webpack v5 起,normalModuleLoader 钩子已被移除。现在要访问加载器,请改用 NormalModule.getCompilationHooks(compilation).loader

statsPreset

HookMap

此 HookMap 类似于当使用预设时触发的一系列操作。它接受一个选项对象。当插件管理预设时,它应该小心地修改此对象中的设置,而不要替换现有设置。

  • 回调参数:options context

这里是一个说明性的插件示例

compilation.hooks.statsPreset.for('my-preset').tap('MyPlugin', (options) => {
  if (options.all === undefined) options.all = true;
});

此插件确保对于预设 'my-preset',如果 all 选项未定义,则默认为 true。

statsNormalize

SyncHook

此钩子用于将选项对象转换为一致的格式,以便后续钩子轻松使用。它还确保缺失的选项被设置为其默认值。

  • 回调参数:options context

这里是一个说明性的插件示例

compilation.hooks.statsNormalize.tap('MyPlugin', (options) => {
  if (options.myOption === undefined) options.myOption = [];

  if (!Array.isArray(options.myOption)) options.myOptions = [options.myOptions];
});

在此插件中,如果 myOption 缺失,它会将其设置为空数组。此外,它确保 myOption 始终是一个数组,即使它最初被定义为单个值。

statsFactory

此钩子提供对 StatsFactory class 的访问,用于特定选项。

  • 回调参数:statsFactory options

StatsFactory.hooks.extract

HookMap

  • 回调参数:object data context

data 包含类。object 是一个应添加属性的对象。context 提供上下文信息,例如路径上的类。

示例

compilation.hooks.statsFactory.tap('MyPlugin', (statsFactory, options) => {
  statsFactory.hooks.extract
    .for('compilation')
    .tap('MyPlugin', (object, compilation) => {
      object.customProperty = MyPlugin.getCustomValue(compilation);
    });
});

StatsFactory.hooks.result

HookMap

在每个级别上用结果调用。

  • 回调参数:result context

statsPrinter

此钩子提供对 StatsPrinter class 的访问,用于特定选项。

  • 回调参数:statsPrinter options

StatsPrinter.hooks.print

HookMap

当某个部分需要打印时,会调用此钩子。

  • 回调参数:object context

StatsPrinter.hooks.result

HookMap

此钩子在某个部分的最终字符串生成时调用。

  • 回调参数:result context

9 贡献者

slavafominbyzykmadhavarshneymisterdevwizardofhogwartsEugeneHlushkochenxsanjamesgeorge007snitin315