---
sidebar_position: 3
---

# Setup function

In the ["Plugin object"](/plugins/guide/plugin-object) section we know that the plugin object contains a `setup` function that not only contains an `api` object parameter, but also returns a Hooks object.

## Plugin API objects

The `setup` function of the plugin will provide an `api` object parameter, and you can call some of the methods provided on this object to get information about the configuration, project context, etc.

```ts
export const myPlugin = (): CliPlugin<ModuleTools> => ({
  name: 'my-plugin',

  setup(api) {
    // Get the original configuration of the application
    const config = api.useConfigContext();
    // Get the application runtime context
    const appContext = api.useAppContext();
    // Get the final configuration after resolving
    const resolvedConfig = api.useResolvedConfigContext();
  },
});
```

### `api.useAppContext`

Used to get project context information.

```ts
const useAppContext: () => IAppContext;

interface IAppContext {
  appDirectory: string;
  configFile: string | false;
  packageName: string;
  nodeModulesDirectory: string;
  internalDirectory: string;
  plugins: {
    cli?: any;
    server?: any;
  }[];
}
```

:::info
Through the actual type file, we can see that there are some additional fields. However, for Modern.js Module, the fields mentioned above are the only ones that are meaningful. The same applies to other methods of the `api` object.
:::

### `api.useResolvedConfigContext`

Used to get the final configuration after parsing.

:::info
If you need to get the build-related final configuration, you need to use the `beforeBuild` Hook.
:::

```ts
const useResolvedConfigContext: () => NormalizedConfig;

interface NormalizedConfig {
  buildConfig: PartialBuildConfig;
  buildPreset: BuildPreset;
  dev: Dev;
  plugins: PluginConfig;
  runtime: RuntimeConfig;
  runtimeByEntries?: RuntimeByEntriesConfig;
  _raw: UserConfig;
}
```

### `api.useHookRunners`

Used to get the executors of Hooks and trigger the execution of a specific Hook.

```ts
import type { CliPlugin } from '@modern-js/core';

export const myPlugin = (): CliPlugin => ({
  name: 'my-plugin',

  async setup(api) {
    const hookRunners = api.useHookRunners();
    // trigger the afterBuild Hook
    await hookRunners.afterBuild();
  },
});
```

## Asynchronous setup

The setup of a CLI plugin can be an asynchronous function that performs asynchronous logic during the initialization process.

```ts
export const myPlugin = (): CliPlugin<ModuleTools> => ({
  name: 'my-plugin',

  async setup(api) {
    await doSomething();
  },
});
```

Note that the setup function of the next plugin is not executed until the async setup function of the current plugin has finished. Therefore, you should avoid performing time-consuming asynchronous operations in the setup function to avoid slowing down the startup performance of the CLI.

## Life cycle hooks

We know that the `setup` function returns a Hooks object, which can also be understood as an object with Modern.js Module lifecycle hooks.

Currently there are two main types of hooks.

- build hooks: triggered only when the `build` command is executed to build the source code product.
- `buildPlatform` hook: triggered only when the `build --platform` command is executed to generate other build artifacts.
- debug hooks: hooks that are triggered when running the `dev` command.

See the [API documentation](/en/api/plugin-api/plugin-hooks) for a full list of lifecycle hooks.
