阅读(4408) (0)

Webpack:compilation 钩子

2023-05-10 16:28:13 更新

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

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

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

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

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​, ​recordChunks​ 和 ​recordHash​)。

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 的数据。

示例:

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

除了 name 和 stage 以外,你还可以传递 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 的列表

    如下是我们可以使用的 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​。