Setup function

In the "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.

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.

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.

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.

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.

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 for a full list of lifecycle hooks.