---
extractApiHeaders: [2]
---

# Plugin Hooks

本章节描述了 Builder 插件提供的生命周期钩子。

## 概览

**通用钩子**

- `modifyBuilderConfig`：修改传递给 Builder 的配置项。
- `modifyBundlerChain` (实验性)：通过 chain api 修改 webpack / Rspack 配置。
- `modifyWebpackChain`：修改 webpack chain 配置。
- `modifyWebpackConfig`：修改最终的 webpack 配置对象。
- `modifyRspackConfig`：修改最终的 Rspack 配置对象。
- `onBeforeCreateCompiler`：在创建 compiler 实例前调用。
- `onAfterCreateCompiler`：在创建 compiler 实例后、执行构建前调用。

**构建钩子**：仅在执行 build 方法构建生产环境产物时调用。

- `onBeforeBuild`：在执行生产环境构建前调用。
- `onAfterBuild`：在执行生产环境构建后调用，可以获取到构建结果信息。

**开发服务钩子**：仅在执行 startDevServer 方法运行开发服务器时调用。

- `onBeforeStartDevServer`：在启动开发服务器前调用。
- `onAfterStartDevServer`：在启动开发服务器后调用。
- `onDevCompileDone`：在每次开发环境构建结束后调用。

**其他钩子**

- `onExit`：在进程即将退出时调用。

## 通用钩子

### modifyBuilderConfig

修改传递给 Builder 的配置项，你可以直接修改传入的 config 对象，也可以返回一个新的对象来替换传入的对象。

- **类型**

```ts
type ModifyWebpackChainUtils = {
  mergeBuilderConfig: typeof mergeBuilderConfig;
};

function ModifyBuilderConfig(
  callback: (
    config: BuilderConfig,
    utils: ModifyWebpackChainUtils,
  ) => PromiseOrNot<BuilderConfig | void>,
): void;
```

- **Example**

```ts
export default () => ({
  setup: api => {
    api.modifyBuilderConfig((config, { mergeBuilderConfig }) => {
      config.html = config.html || {};
      config.html.title = 'Hello World!';
      return mergeBuilderConfig(config, {
        source: { preEntry: 'foo.js' },
      });
    });
  },
});
```

### modifyBundlerChain `实验性`

:::tip 什么是 BundlerChain

import BundlerChain from '@zh/shared/bundlerChain.md';

<BundlerChain />
:::

`modifyBundlerChain` 用于调用 bundler chain 来修改 webpack / Rspack 的配置。你在使用 webpack-provider 或 rspack-provider 时都可以使用该 hook。

- **类型**

```ts
type ModifyBunlderChainUtils = {
  env: NodeEnv;
  isProd: boolean;
  target: BuilderTarget;
  isServer: boolean;
  isWebWorker: boolean;
  CHAIN_ID: ChainIdentifier;
  HtmlPlugin: typeof import('html-webpack-plugin');
};

function ModifyBundlerChain(
  callback: (
    chain: BundlerChain,
    utils: ModifyBunlderChainUtils,
  ) => Promise<void> | void,
): void;
```

- **Example**

```ts
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';

export default () => ({
  setup: api => {
    api.modifyBundlerChain((chain, utils) => {
      if (utils.env === 'development') {
        chain.devtool('eval');
      }

      chain.plugin('bundle-analyze').use(BundleAnalyzerPlugin);
    });
  },
});
```

### modifyWebpackChain

通过 webpack chain 来修改 webpack 配置。该方法仅在使用 webpack-provider 时调用。

- **类型**

```ts
type ModifyWebpackChainUtils = {
  env: NodeEnv;
  isProd: boolean;
  target: BuilderTarget;
  webpack: typeof import('webpack');
  isServer: boolean;
  isWebWorker: boolean;
  CHAIN_ID: ChainIdentifier;
  getCompiledPath: (name: string) => string;
  HtmlWebpackPlugin: typeof import('html-webpack-plugin');
};

function ModifyWebpackChain(
  callback: (
    chain: WebpackChain,
    utils: ModifyWebpackChainUtils,
  ) => Promise<void> | void,
): void;
```

- **Example**

```ts
export default () => ({
  setup: api => {
    api.modifyWebpackChain((chain, utils) => {
      if (utils.env === 'development') {
        chain.devtool('eval');
      }
    });
  },
});
```

### modifyWebpackConfig

修改最终的 webpack 配置对象，你可以直接修改传入的 config 对象，也可以返回一个新的对象来替换传入的对象。该方法仅在使用 webpack-provider 时调用。

该方法的调用时机晚于 `modifyWebpackChain` 钩子。

- **类型**

```ts
type ModifyWebpackConfigUtils = {
  env: NodeEnv;
  isProd: boolean;
  target: BuilderTarget;
  webpack: typeof import('webpack');
  isServer: boolean;
  isWebWorker: boolean;
  CHAIN_ID: ChainIdentifier;
  getCompiledPath: (name: string) => string;
  HtmlWebpackPlugin: typeof import('html-webpack-plugin');
  addRules: (rules: RuleSetRule | RuleSetRule[]) => void;
  prependPlugins: (
    plugins: WebpackPluginInstance | WebpackPluginInstance[],
  ) => void;
  appendPlugins: (
    plugins: WebpackPluginInstance | WebpackPluginInstance[],
  ) => void;
  removePlugin: (pluginName: string) => void;
};

function ModifyWebpackConfig(
  callback: (
    config: WebpackConfig,
    utils: ModifyWebpackConfigUtils,
  ) => Promise<WebpackConfig | void> | WebpackConfig | void,
): void;
```

- **Example**

```ts
export default () => ({
  setup: api => {
    api.modifyWebpackConfig((config, utils) => {
      if (utils.env === 'development') {
        config.devtool = 'eval';
      }
    });
  },
});
```

### modifyRspackConfig

修改最终的 Rspack 配置对象，你可以直接修改传入的 config 对象，也可以返回一个新的对象来替换传入的对象。该方法仅在使用 rspack-provider 时调用。

- **类型**

```ts
type ModifyRspackConfigUtils = {
  env: NodeEnv;
  isProd: boolean;
  target: BuilderTarget;
  isServer: boolean;
  isWebWorker: boolean;
  getCompiledPath: (name: string) => string;
};

function ModifyRspackConfig(
  callback: (
    config: RspackConfig,
    utils: ModifyRspackConfigUtils,
  ) => Promise<RspackConfig | void> | RspackConfig | void,
): void;
```

- **Example**

```ts
export default () => ({
  setup: api => {
    api.modifyRspackConfig((config, utils) => {
      if (utils.env === 'development') {
        config.devtool = 'eval';
      }
    });
  },
});
```

### onBeforeCreateCompiler

import OnBeforeCreateCompiler from '@zh/shared/onBeforeCreateCompiler.md';

<OnBeforeCreateCompiler />

- **Example**

```ts
export default () => ({
  setup: api => {
    api.onBeforeCreateCompiler(({ bundlerConfigs }) => {
      console.log('the bundler config is ', bundlerConfigs);
    });
  },
});
```

### onAfterCreateCompiler

import OnAfterCreateCompiler from '@zh/shared/onAfterCreateCompiler.md';

<OnAfterCreateCompiler />

- **Example**

```ts
export default () => ({
  setup: api => {
    api.onAfterCreateCompiler(({ compiler }) => {
      console.log('the compiler is ', compiler);
    });
  },
});
```

## 构建钩子

### onBeforeBuild

import OnBeforeBuild from '@zh/shared/onBeforeBuild.md';

<OnBeforeBuild />

- **Example**

```ts
export default () => ({
  setup: api => {
    api.onBeforeBuild(({ bundlerConfigs }) => {
      console.log('the bundler config is ', bundlerConfigs);
    });
  },
});
```

### onAfterBuild

import OnAfterBuild from '@zh/shared/onAfterBuild.md';

<OnAfterBuild />

- **Example**

```ts
export default () => ({
  setup: api => {
    api.onAfterBuild(({ stats }) => {
      console.log(stats?.toJson());
    });
  },
});
```

## 开发服务钩子

### onBeforeStartDevServer

import OnBeforeStartDevServer from '@zh/shared/onBeforeStartDevServer.md';

<OnBeforeStartDevServer />

- **Example**

```ts
export default () => ({
  setup: api => {
    api.onBeforeStartDevServer(() => {
      console.log('before start!');
    });
  },
});
```

### onAfterStartDevServer

import OnAfterStartDevServer from '@zh/shared/onAfterStartDevServer.md';

<OnAfterStartDevServer />

- **Example**

```ts
export default () => ({
  setup: api => {
    api.onAfterStartDevServer(({ port }) => {
      console.log('this port is: ', port);
    });
  },
});
```

### onDevCompileDone

import OnDevCompileDone from '@zh/shared/onDevCompileDone.md';

<OnDevCompileDone />

- **Example**

```ts
export default () => ({
  setup: api => {
    api.onDevCompileDone(({ isFirstCompile }) => {
      if (isFirstCompile) {
        console.log('first compile!');
      } else {
        console.log('re-compile!');
      }
    });
  },
});
```

## 其他钩子

### onExit

import OnExit from '@zh/shared/onExit.md';

<OnExit />

- **Example**

```ts
export default () => ({
  setup: api => {
    api.onExit(() => {
      console.log('exit!');
    });
  },
});
```
