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/runtime-plugins/api.md.
  • 简体中文
  • 插件 API

    Modern.js 的 Runtime 插件允许您在应用程序的 React 代码运行时扩展和修改其行为。通过 Runtime 插件,您可以轻松地执行初始化任务、实现 React 高阶组件(HOC)封装等功能。

    Info

    Runtime 插件需要通过 src/modern.runtime.ts 中的 plugins 字段配置。

    插件结构

    一个典型的 Runtime 插件如下所示:

    import type { RuntimePlugin } from '@modern-js/runtime';
    
    const myRuntimePlugin = (): RuntimePlugin => ({
      name: 'my-runtime-plugin',
      setup: api => {
        // 使用 api 注册钩子
        api.onBeforeRender(context => {
          console.log('Before rendering:', context);
        });
    
        api.wrapRoot(App => {
          return props => (
            <MyContextProvider>
              <App {...props} />
            </MyContextProvider>
          );
        });
      },
    });
    
    export default myRuntimePlugin;
    • name: 插件的唯一标识符。
    • setup: 函数接收一个 api 对象,该对象提供了所有可用的 Runtime 插件 API。

    API 概览

    Runtime 插件 API 主要分为以下几类:

    • 信息获取:获取运行时配置和钩子函数。
    • 生命周期钩子:在应用渲染的不同阶段执行自定义逻辑。

    信息获取

    api.getRuntimeConfig

    获取用户在 modern.runtime.ts 文件中定义的运行时配置。

    • 用法:
    const config = api.getRuntimeConfig();
    console.log(config.myCustomSetting);
    Warning

    此方法返回的是用户配置的副本,修改返回值不会影响原始配置。

    api.getHooks

    获取可用于手动触发的钩子函数。

    • 类型:
    () => {
      onBeforeRender: {
        call: (context: any) => Promise<void>;
      }
      // 其他钩子...
    };
    • 用法:
    const hooks = api.getHooks();
    await hooks.onBeforeRender.call(myContext);

    生命周期钩子

    api.onBeforeRender

    在应用渲染(包括服务器端渲染和客户端渲染)之前执行。您可以在此钩子中执行数据预取、修改渲染上下文等操作。

    • 类型:

      type OnBeforeRenderFn<RuntimeContext> = (
        context: RuntimeContext,
      ) => Promise<void> | void;

      RuntimeContext 包含当前请求的上下文信息,如请求对象、响应对象等。

    • 用法:

      api.onBeforeRender(async context => {
        const data = await fetchData(context.req);
        context.data = data; // 将数据添加到上下文中
      });
    Warning
    • 此钩子在每次渲染前都会执行,因此应避免执行耗时过长的操作。
    • 您可以在此钩子中修改 context 对象,并将修改后的 context 传递给后续的渲染过程。

    api.wrapRoot

    允许您使用自定义的 React 组件包裹应用的根组件。常用于添加全局的 Provider、布局组件等。

    • 类型:

      type WrapRootFn = (App: React.ComponentType<any>) => React.ComponentType<any>;
    • 用法:

      api.wrapRoot(App => {
        const AppWrapper = props => {
          return (
            <MyGlobalProvider>
              <Layout>
                <App {...props} /> {/* 确保传递 props */}
              </Layout>
            </MyGlobalProvider>
          );
        };
        return AppWrapper;
      });
    Warning
    • 务必将 props 传递给原始的 App 组件,否则可能导致应用无法正常工作。
    • wrapRoot 返回的组件会在每次渲染时重新创建,因此应避免在其中定义复杂的逻辑或状态。

    进阶用法

    组合使用钩子

    您可以组合使用多个钩子来实现更复杂的功能。例如,您可以使用 onBeforeRender 获取数据,然后使用 wrapRoot 将数据通过 Context 传递给整个应用:

    import { RuntimePlugin, RuntimeContext } from '@modern-js/runtime';
    import { useContext, createContext } from 'react';
    
    export const ThemeContext = createContext<{ theme: string } | null>(null);
    
    export const themePlugin = (): RuntimePlugin => {
      return {
        name: 'theme-plugin',
        setup: api => {
          api.onBeforeRender(async context => {
            const userPreference = await fetch('/api/user/theme-settings').then(
              res => res.json(),
            );
            context.data = {
              theme: userPreference.theme,
            };
          });
    
          api.wrapRoot(App => {
            return props => {
              const context = useContext(RuntimeContext);
              return (
                <ThemeContext.Provider value={context.data}>
                  <App {...props} />
                </ThemeContext.Provider>
              );
            };
          });
        },
      };
    };