For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt, and this page is available as Markdown at /zh/plugin/cli-plugins/api.md.
  • 简体中文
  • 插件 API

    Modern.js 的 CLI 插件允许您在 Modern.js 项目的构建和开发过程中扩展和定制功能。

    Info

    CLI 插件需要通过 modern.config.ts 中的 plugins 字段配置。

    插件基础结构

    一个典型的 CLI 插件结构如下:

    import type { CliPlugin, AppTools } from '@modern-js/app-tools';
    
    const myCliPlugin = (): CliPlugin<AppTools> => ({
      name: '@my-org/my-plugin', // 插件名称,确保唯一性
      setup: api => {
        // 在这里使用 API 注册钩子、添加命令等
        api.onBeforeBuild(() => {
          console.log('构建即将开始...');
        });
      },
    });
    
    export default myCliPlugin;
    • name: 插件的唯一标识符。
    • setup 函数接收一个 api 对象,该对象提供了所有可用的 CLI 插件 API。

    信息获取

    api.getAppContext

    获取 Modern.js 应用的上下文信息。

    • 返回值: AppContext 对象,包含以下字段:
    字段名类型描述何时可用
    commandstring当前执行的命令 (e.g., dev, build, deploy)-
    portnumber开发服务器端口号onPrepare 之后
    configFilestring配置文件的绝对路径-
    isProdboolean是否为生产模式-
    appDirectorystring项目根目录的绝对路径-
    srcDirectorystring项目源码目录的绝对路径-
    distDirectorystring项目产物输出目录的绝对路径onPrepare(及之后)
    sharedDirectorystring公共模块目录的绝对路径-
    nodeModulesDirectorystringnode_modules 目录的绝对路径-
    ipstring当前机器的 IPv4 地址-
    packageNamestring项目 package.json 中的 name 字段-
    pluginsobject[]当前已注册的插件列表-
    entrypointsobject[]页面入口信息-
    serverRoutesobject[]服务端路由信息-
    bundlerTyperspack当前使用的打包工具类型onPrepare 之后
    metaNamestring框架内部名称-
    apiDirectorystringAPI 模块目录的绝对路径 (BFF 使用)-
    lambdaDirectorystringLambda 模块目录的绝对路径 (BFF 使用)-
    runtimeConfigFilestring运行时配置文件的名称-
    checkedEntriesstring[]指定的入口信息-
    apiOnlyboolean是否为 apiOnly 模式-
    • 示例:
    api.onPrepare(() => {
      const appContext = api.getAppContext();
      console.log(`当前项目运行在 ${appContext.isProd ? '生产' : '开发'} 模式`);
      console.log(`打包工具: ${appContext.bundlerType}`);
    });
    Info

    getAppContext 返回的上下文信息是只读的,无法直接进行修改。


    api.getConfig

    获取用户在 modern.config.ts 文件中定义的配置。

    • 返回值: 用户定义的配置对象。
    • 示例:
    api.onPrepare(() => {
      const userConfig = api.getConfig();
      if (userConfig.output) {
        console.log('用户自定义了 output 配置');
      }
    });

    api.getNormalizedConfig

    获取经过 Modern.js 内部处理和插件修改后的最终配置(归一化配置)。

    • 返回值: 归一化后的配置对象。
    • 何时可用: 必须在 onPrepare(及之后的 hook,例如 onBeforeBuild)中使用。
    • 示例:
    api.onPrepare(() => {
      const finalConfig = api.getNormalizedConfig();
      console.log('最终配置:', finalConfig);
    });

    api.isPluginExists

    检查指定的插件是否已注册。

    • 参数:
      • pluginName: string: 要检查的插件名称。
    • 返回值: boolean 值,表示插件是否存在。
    • 示例:
    if (api.isPluginExists('@modern-js/plugin-bff')) {
      console.log('BFF 插件已启用');
    }

    api.getHooks

    获取所有已注册的钩子函数。

    • 返回值: 包含所有钩子函数的对象。
    • 示例:
    const hooks = api.getHooks();
    // 手动触发 onPrepare 钩子
    hooks.onPrepare.call();
    Warning

    在自定义插件中,只能手动调用对应插件注册的钩子,不能调用官方钩子,以免影响正常应用的执行顺序。


    配置修改

    api.config

    修改 Modern.js 的初始配置。

    • 类型: api.config(configFn: () => UserConfig | Promise<UserConfig>)
    • 参数:
      • configFn: 一个返回配置对象或 Promise 的函数。
    • 执行阶段: 解析完 modern.config.ts 中的配置之后。
    • 示例:
    api.config(() => {
      return {
        output: {
          disableTsChecker: true, // 关闭 TypeScript 类型检查
        },
      };
    });

    配置合并优先级(从高到低):

    1. 用户在 modern.config.* 文件中定义的配置。
    2. 插件通过 api.config() 注册的配置。
    3. Modern.js 默认配置。

    api.modifyBundlerChain

    使用 chain API 修改 Rspack 配置。

    • 类型: api.modifyBundlerChain(modifyFn: (chain: RspackChain, utils: RspackUtils) => void | Promise<void>)
    • 参数:
      • modifyFn: 修改函数,接收 RspackChain 实例和实用工具作为参数。
    • 执行阶段: 在生成最终的 Rspack 配置时。
    • 对应 Rsbuild Hook: modifybundlerchain
    • 示例:
    api.modifyBundlerChain((chain, utils) => {
      if (utils.env === 'development') {
        chain.devtool('eval');
      }
      chain.plugin('bundle-analyze').use(BundleAnalyzerPlugin);
    });

    api.modifyRsbuildConfig

    修改 Rsbuild 的配置。

    • 类型: api.modifyRsbuildConfig(modifyFn: (config: RsbuildConfig, utils: RsbuildUtils) => RsbuildConfig | Promise<RsbuildConfig> | void)
    • 参数:
      • modifyFn: 修改函数,接收 Rsbuild 配置对象和实用工具作为参数,可以返回修改后的配置对象、Promise 或不返回(直接修改原对象)。
    • 执行阶段: 在生成最终的 Rsbuild 配置时。
    • 对应 Rsbuild Hook: modifyRsbuildConfig
    • 示例:
    api.modifyRsbuildConfig((config, utils) => {
      // 添加一个自定义的 Rsbuild 插件
      config.plugins.push(myCustomRsbuildPlugin());
    });

    api.modifyRspackConfig

    修改 Rspack 的配置。(当使用 Rspack 作为打包工具时)

    • 类型: api.modifyRspackConfig(modifyFn: (config: RspackConfig, utils: RspackUtils) => RspackConfig | Promise<RspackConfig> | void)
    • 参数:
      • modifyFn: 修改函数,接收 Rspack 配置对象和实用工具作为参数,可以返回修改后的配置对象、Promise 或不返回(直接修改原对象)。
    • 执行阶段: 在生成最终的 Rspack 配置时。
    • 对应 Rsbuild Hook: modifyRspackConfig
    • 示例:
    api.modifyRspackConfig((config, utils) => {
      config.builtins.minify = {
        enable: true,
        implementation: utils.rspack.SwcJsMinimizerRspackPlugin,
      };
    });

    构建配置修改顺序

    modifyRsbuildConfig
    modifyBundlerChain
    tools.bundlerChain
    modifyRspackConfig
    tools.rspack

    api.modifyServerRoutes

    修改服务器路由配置。

    • 类型 api.modifyServerRoutes(transformFn: (routes: ServerRoute[]) => ServerRoute[])
    • 参数:
      • transformFn: 转换函数,接收当前服务器路由数组作为参数,返回修改后的数组。
    • 执行阶段: 在生成服务器路由文件之前 ( prepare 阶段)。
    • 示例:
    api.modifyServerRoutes(routes => {
      // 添加一个新的 API 路由
      routes.push({
        urlPath: '/api',
        isApi: true,
        entryPath: '',
        isSPA: false,
        isSSR: false,
      });
      return routes;
    });

    api.modifyHtmlPartials

    修改 HTML 模板片段。

    • 类型 api.modifyHtmlPartials(modifyFn: (partials: HtmlPartials, entrypoint: Entrypoint) => void)
    • 参数:
      • modifyFn: 修改函数,接收 HTML 模板片段对象和当前入口点信息作为参数。
        • partials: 包含 top, head, body 三个部分,每个部分都有append, prepend, replace三个方法。
    • 执行阶段: 在生成 HTML 文件之前 ( prepare 阶段)。
    • 示例:
    api.modifyHtmlPartials(({ entrypoint, partials }) => {
      // 在所有页面的 <head> 标签中添加一个 meta 标签
      if (partials.head && partials.head.append) {
        partials.head.append(`<meta name="my-custom-meta" content="value">`);
      }
    });
    Warning

    当使用完全自定义模板时,该钩子函数将不会执行。


    构建流程控制

    api.onPrepare

    在 Modern.js 准备阶段添加额外的逻辑。

    • 类型 api.onPrepare(prepareFn: () => void | Promise<void>)
    • 参数:
      • prepareFn: 准备函数,无参数,可异步。
    • 执行阶段: 在 Modern.js 完成配置校验之后。
    • 示例:
    api.onPrepare(async () => {
      // 执行一些初始化操作,例如检查环境、下载依赖等
      await prepareMyCustomEnvironment();
    });

    api.addCommand

    添加自定义的 CLI 命令。

    • 类型 api.addCommand(commandFn: ({ program: Command }) => void)
    • 参数:
      • commandFn: 接收 commander 的 program 对象作为参数,用于定义新的命令。
    • 执行阶段: prepare 钩子运行完成后。
    • 示例:
    api.addCommand(({ program }) => {
      program
        .command('my-command')
        .description('我的自定义命令')
        .action(async () => {
          // 执行命令逻辑
          console.log('执行自定义命令...');
        });
    });

    api.addWatchFiles

    添加额外的文件监听列表(用于开发模式)。

    • 类型 api.addWatchFiles(watchFn: () => string[] | { files: string[]; isPrivate: boolean; })
    • 参数:
      • watchFn: 返回一个包含文件路径的数组,或一个包含 files 和 isPrivate 属性的对象。
        • files: 要监听的文件路径数组。
        • isPrivate: 是否为框架内部文件(影响文件变更时的行为)。
    • 执行阶段: addCommand 钩子运行完成之后。
    • 示例:
    api.addWatchFiles(() => {
      // 监听项目根目录下的 .env 文件
      return [path.resolve(api.getAppContext().appDirectory, '.env')];
    });

    api.onFileChanged

    在监听文件发生变化时添加额外的逻辑(用于开发模式)。

    • 类型 api.onFileChanged(changeFn: (params: { filename: string; eventType: 'add' | 'change' | 'unlink'; isPrivate: boolean; }) => void)
    • 参数:
      • changeFn: 文件变化处理函数,接收以下参数:
        • filename: 发生变化的文件路径。
        • eventType: 变化类型 (add, change, unlink)。
        • isPrivate: 是否为框架内部文件。
    • 执行阶段: 监听文件变化之后。
    • 示例:
    api.onFileChanged(({ filename, eventType }) => {
      if (eventType === 'change' && filename.endsWith('.ts')) {
        console.log('TypeScript 文件发生变化,可能需要重新编译...');
      }
    });

    api.onBeforeBuild

    在构建开始之前添加额外的逻辑。

    • 类型 api.onBeforeBuild(buildFn: () => void | Promise<void>)
    • 参数:
      • buildFn: 构建前执行的函数,无参数,可异步。
    • 执行阶段: 在执行构建流程之前。
    • 对应 Rsbuild Hook: onBeforeBuild
    • 示例:
    api.onBeforeBuild(() => {
      // 构建前做一些环境检查
    });

    api.onAfterBuild

    在构建完成后添加额外的逻辑。

    • 类型: api.onAfterBuild(buildFn: () => void | Promise<void>)
    • 参数:
      • buildFn: 构建后执行的函数,无参数,可异步。
    • 执行阶段: 在执行构建流程之后。
    • 对应 Rsbuild Hook: onAfterBuild
    • 示例:
    api.onAfterBuild(() => {
      // 构建后上传sourceMap
    });

    api.onDevCompileDone

    在开发服务器编译完成后添加额外的逻辑。

    • 类型: api.onDevCompileDone(compileFn: () => void | Promise<void>)
    • 参数:
      • compileFn: 编译完成后执行的函数。
    • 执行阶段: 开发服务器启动,且首次编译完成后。
    • 对应 Rsbuild Hook: onDevCompileDone
    • 示例:
    api.onDevCompileDone(() => {
      // 首次编译完成,打开浏览器
    });

    api.onBeforeCreateCompiler

    在创建编译器实例之前添加额外的逻辑。

    • 类型: api.onBeforeCreateCompiler(createFn: () => void | Promise<void>)
    • 参数:
      • createFn: 创建前执行的函数,无参数,可异步。
    • 执行阶段: 在创建 Rspack 编译器实例之前。
    • 对应 Rsbuild Hook: onBeforeCreateCompiler
    • 示例:
    api.onBeforeCreateCompiler(() => {
      // 可以获取 compiler 相关配置
    });

    api.onAfterCreateCompiler

    在创建编译器实例之后添加额外的逻辑。

    • 类型: api.onAfterCreateCompiler(createFn: () => void | Promise<void>)
    • 参数:
      • createFn: 创建后执行的函数,无参数,可异步。
    • 执行阶段: 在创建 Rspack 编译器实例之后。
    • 对应 Rsbuild Hook: onAfterCreateCompiler
    • 示例:
    api.onAfterCreateCompiler(() => {
      // 可以获取 compiler 实例
    });

    api.onBeforeDev

    在开发服务器启动前添加额外的逻辑。

    • 类型: api.onBeforeDev(devFn: () => void | Promise<void>)
    • 参数:
      • devFn: 开发服务器启动前执行的函数,无参数,可异步。
    • 执行阶段: 在执行 dev 命令启动开发服务器之前。
    • 示例:
    api.onBeforeDev(async () => {
      // 检查端口是否被占用
      await checkPortAvailability(3000);
    });

    api.onAfterDev

    在开发服务器启动后添加额外的逻辑。

    • 类型: api.onAfterDev(devFn: () => void | Promise<void>)
    • 参数:
      • devFn: 开发服务器启动后执行的函数。
    • 执行阶段: 开发服务器成功启动后。
    • 对应 Rsbuild Hook: onAfterStartDevServer
    • 示例:
    api.onAfterDev(() => {
      // 上报 dev 相关信息
    });

    api.onBeforeExit

    在进程退出前添加额外的逻辑。

    • 类型: api.onBeforeExit(exitFn: () => void | Promise<void>)
    • 参数:
      • exitFn: 进程退出前执行的函数,无参数,可异步。
    • 执行阶段: 在 Modern.js 进程即将退出时(例如,用户按下 Ctrl+C)。
    • 示例:
    api.onBeforeExit(async () => {
      // 执行一些清理操作,例如关闭数据库连接、删除临时文件等
      await cleanupMyResources();
    });

    api.onBeforePrintInstructions

    在打印成功信息前添加额外的逻辑。

    • 类型: api.onBeforePrintInstructions(printFn: ({instructions: string}) => {instructions: string} | Promise<{instructions: string}>)
    • 参数:
      • printFn: 修改打印信息的函数, 返回修改后的信息。
    • 执行阶段: 打印成功信息前。
    • 示例:
    api.onBeforePrintInstructions(({ instructions }) => {
      // do something
      return { instructions };
    });

    其他说明