首页 > 其他分享 >第144篇:阿里低开项目 init方法

第144篇:阿里低开项目 init方法

时间:2024-03-20 13:48:00浏览次数:24  
标签:engine 初始化 144 container 低开 插件 init engineContainer

好家伙,

 

 demo-general项目运行后主界面如下

 

解析阿里低开引擎中的初始化方法init

拆解项目来自阿里的lowcode engine目录下的 demo general项目

0.找到入口文件

可以看到整个项目用到的插件非常之多

于是

  1. init: init 方法用于初始化低代码引擎,负责加载各种插件并配置引擎的运行环境。

  2. plugins: plugins 是一个插件集合,包含了多个插件,用于扩展低代码引擎的功能。

  3. createFetchHandler: createFetchHandler 方法用于创建一个数据源的处理器,用于处理数据源相关的操作。

  4. EditorInitPlugin: 编辑器初始化插件,用于初始化低代码引擎的编辑器。

  5. UndoRedoPlugin: 撤销重做插件,提供撤销和重做操作的功能。

  6. ZhEnPlugin: 中英文切换插件,用于实现界面语言的切换。

  7. CodeGenPlugin: 代码生成插件,用于生成代码。

  8. DataSourcePanePlugin: 数据源面板插件,用于管理数据源。

  9. SchemaPlugin: Schema 插件,用于处理数据模型的定义和管理。

  10. CodeEditorPlugin: 代码编辑器插件,用于提供代码编辑功能。

  11. ManualPlugin: 手册插件,提供用户手册和帮助文档。

  12. InjectPlugin: 注入插件,用于注入特定功能或代码。

  13. SimulatorResizerPlugin: 模拟器调整插件,用于调整模拟器的大小。

  14. ComponentPanelPlugin: 组件面板插件,用于管理可用组件。

  15. DefaultSettersRegistryPlugin: 默认设置注册插件,用于注册默认设置。

  16. LoadIncrementalAssetsWidgetPlugin: 加载增量资源小部件插件,用于加载增量资源。

  17. SaveSamplePlugin: 保存示例插件,用于保存示例代码。

  18. PreviewSamplePlugin: 预览示例插件,用于预览示例代码。

  19. CustomSetterSamplePlugin: 自定义设置示例插件,用于自定义设置示例。

  20. SetRefPropPlugin: 设置引用属性插件,用于设置引用属性。

  21. LogoSamplePlugin: Logo 示例插件,用于展示 Logo 示例。

  22. SimulatorLocalePlugin: 模拟器语言插件,用于设置模拟器的语言。

  23. lowcodePlugin: 低代码组件插件,用于提供低代码组件功能。

  24. appHelper: 应用程序辅助方法,可能包含一些辅助函数或工具函数。

  25. global.scss: 全局样式文件,定义了全局的样式规则

那么把我们主要要解析的文件拿出来

就这行

import { init, plugins } from '@alilc/lowcode-engine';

 

1.官方文档定位包位置

 

2.在lowcode-engine中寻找init方法

 直接找到

engine-core引擎核心,是他没错了

 

我们来看看这段代码到底在做什么?

//engine-core.ts
export async function init( container?: HTMLElement, options?: IPublicTypeEngineOptions, pluginPreference?: PluginPreference, ) { await destroy(); let engineOptions = null; if (isPlainObject(container)) { engineOptions = container; engineContainer = document.createElement('div'); engineContainer.id = 'engine'; document.body.appendChild(engineContainer); } else { engineOptions = options; engineContainer = container; if (!container) { engineContainer = document.createElement('div'); engineContainer.id = 'engine'; document.body.appendChild(engineContainer); } } engineConfig.setEngineOptions(engineOptions as any); const { Workbench } = common.skeletonCabin; if (options && options.enableWorkspaceMode) { const disposeFun = await pluginPromise; disposeFun && disposeFun(); render( createElement(WorkSpaceWorkbench, { workspace: innerWorkspace, // skeleton: workspace.skeleton, className: 'engine-main', topAreaItemClassName: 'engine-actionitem', }), engineContainer, ); innerWorkspace.enableAutoOpenFirstWindow = engineConfig.get('enableAutoOpenFirstWindow', true); innerWorkspace.setActive(true); innerWorkspace.initWindow(); innerHotkey.activate(false); await innerWorkspace.plugins.init(pluginPreference); return; } await plugins.init(pluginPreference as any); render( createElement(Workbench, { skeleton: innerSkeleton, className: 'engine-main', topAreaItemClassName: 'engine-actionitem', }), engineContainer, ); }

 

回到前面demo-general项目中中初始化部分

//index.tx
(async function main() {
  await registerPlugins();

  init(document.getElementById('lce-container')!, {
    locale: 'zh-CN',
    enableCondition: true,
    enableCanvasLock: true,
    // 默认绑定变量
    supportVariableGlobally: true,
    requestHandlersMap: {
      fetch: createFetchHandler(),
    },
    appHelper,
  });
})();

 

 

3.解释init()

export async function init(
  container?: HTMLElement, // 初始化函数参数:容器元素,可选
  options?: IPublicTypeEngineOptions, // 初始化函数参数:引擎选项,可选
  pluginPreference?: PluginPreference, // 初始化函数参数:插件偏好设置,可选
) {
  await destroy(); // 销毁之前的状态,确保初始化干净

  let engineOptions = null; // 初始化引擎选项变量

  if (isPlainObject(container)) { // 如果容器是一个普通对象
    engineOptions = container; // 将容器作为引擎选项
    engineContainer = document.createElement('div'); // 创建一个新的 div 元素作为引擎容器
    engineContainer.id = 'engine'; // 设置容器的 id 为 'engine'
    document.body.appendChild(engineContainer); // 将容器添加到 body 中
  } else {
    engineOptions = options; // 使用传入的引擎选项
    engineContainer = container; // 使用传入的容器
    if (!container) { // 如果容器不存在
      engineContainer = document.createElement('div'); // 创建一个新的 div 元素作为引擎容器
      engineContainer.id = 'engine'; // 设置容器的 id 为 'engine'
      document.body.appendChild(engineContainer); // 将容器添加到文档的 body 中
    }
  }

  engineConfig.setEngineOptions(engineOptions as any); // 设置引擎配置的选项

  const { Workbench } = common.skeletonCabin; // 从骨架中解构出 Workbench 组件

  if (options && options.enableWorkspaceMode) { // 如果启用工作区模式
    const disposeFun = await pluginPromise; // 等待插件 Promise 的解析
    disposeFun && disposeFun(); // 如果存在 disposeFun 函数,则执行

    render( // 渲染工作区工作台组件
      createElement(WorkSpaceWorkbench, {
        workspace: innerWorkspace, // 传入内部工作区
        className: 'engine-main', // 设置类名
        topAreaItemClassName: 'engine-actionitem', // 设置顶部区域项的类名
      }),
      engineContainer, // 渲染到引擎容器中
    );

    innerWorkspace.enableAutoOpenFirstWindow = engineConfig.get('enableAutoOpenFirstWindow', true); // 设置内部工作区自动打开第一个窗口的属性
    innerWorkspace.setActive(true); // 设置工作区为活动状态
    innerWorkspace.initWindow(); // 初始化窗口
    innerHotkey.activate(false); // 激活快捷键
    await innerWorkspace.plugins.init(pluginPreference); // 初始化工作区插件
    return; // 返回
  }

  await plugins.init(pluginPreference as any); // 初始化插件

  render( // 渲染工作台组件
    createElement(Workbench, {
      skeleton: innerSkeleton, // 传入内部骨架
      className: 'engine-main', // 设置类名
      topAreaItemClassName: 'engine-actionitem', // 设置顶部区域项的类名
    }),
    engineContainer, // 渲染到引擎容器中
  );
}

 

再来找

 

 最后,来到workbench.tsx中

 

4.workbench.tsx

export class Workbench extends Component<{
  workspace: Workspace; // 工作空间对象
  config?: EditorConfig; // 编辑器配置(可选)
  components?: PluginClassSet; // 插件类集合
  className?: string; // 类名
  topAreaItemClassName?: string; // 顶部区域项的类名
}, {
  workspaceEmptyComponent: any; // 工作空间为空时的组件
  theme?: string; // 主题
}> {
  constructor(props: any) {
    super(props);
    const { config, components, workspace } = this.props;
    const { skeleton } = workspace;
    skeleton.buildFromConfig(config, components); // 从配置和组件构建骨架
    engineConfig.onGot('theme', (theme) => {
      this.setState({
        theme,
      });
    });
    engineConfig.onGot('workspaceEmptyComponent', (workspaceEmptyComponent) => {
      this.setState({
        workspaceEmptyComponent,
      });
    });
    this.state = {
      workspaceEmptyComponent: engineConfig.get('workspaceEmptyComponent'), // 获取工作空间为空时的组件
      theme: engineConfig.get('theme'), // 获取主题
    };
  }

  render() {
    const { workspace, className, topAreaItemClassName } = this.props;
    const { skeleton } = workspace;
    const { workspaceEmptyComponent: WorkspaceEmptyComponent, theme } = this.state;

    return (
      <div className={classNames('lc-workspace-workbench', className, theme)}>
        <SkeletonContext.Provider value={skeleton}>
          <TopArea className="lc-workspace-top-area" area={skeleton.topArea} itemClassName={topAreaItemClassName} /> {/* 渲染顶部区域 */}
          <div className="lc-workspace-workbench-body">
            <LeftArea className="lc-workspace-left-area lc-left-area" area={skeleton.leftArea} /> {/* 渲染左侧区域 */}
            <LeftFloatPane area={skeleton.leftFloatArea} /> {/* 渲染左侧浮动区域 */}
            <LeftFixedPane area={skeleton.leftFixedArea} /> {/* 渲染左侧固定区域 */}
            <div className="lc-workspace-workbench-center">
              <div className="lc-workspace-workbench-center-content">
                <SubTopArea area={skeleton.subTopArea} itemClassName={topAreaItemClassName} /> {/* 渲染中上区域 */}
                <div className="lc-workspace-workbench-window">
                  {
                    workspace.windows.map(d => (
                      <WindowView
                        active={d.id === workspace.window?.id} // 判断窗口是否激活
                        window={d}
                        key={d.id}
                      />
                    ))
                  }

                  {
                    !workspace.windows.length && WorkspaceEmptyComponent ? <WorkspaceEmptyComponent /> : null // 根据条件渲染工作空间为空时的组件
                  }
                </div>
              </div>
              <MainArea area={skeleton.mainArea} /> {/* 渲染主区域 */}
              <BottomArea area={skeleton.bottomArea} /> {/* 渲染底部区域 */}
            </div>
            {/* <RightArea area={skeleton.rightArea} /> */}
          </div>
          <TipContainer /> {/* 渲染提示容器 */}
        </SkeletonContext.Provider>
      </div>
    );
  }
}

 

5.main-area.tsx

export default class MainArea extends Component<{ area: Area<any, Panel | Widget> }> {
  render() {
    const { area } = this.props;
    return (
      <div className={classNames('lc-main-area engine-workspacepane')}>
        {area.container.items.map((item) => item.content)}
      </div>
    );
  }
}

以上代码,

将area.container.items数组中每个元素的content属性渲染到页面上,展示在MainArea组件所代表的区域内。

 

至此,低开引擎的初始化完成

 

标签:engine,初始化,144,container,低开,插件,init,engineContainer
From: https://www.cnblogs.com/FatTiger4399/p/18081298

相关文章

  • 洛谷-P1449 后缀表达式
    目录 何为后缀表达式?模拟过程AC代码采用STL的stack题目链接:P1449后缀表达式-洛谷|计算机科学教育新生态(luogu.com.cn) 何为后缀表达式?那后缀表达式是怎么算的呢那显然就需要引用最开始说的栈了因为后缀表表达式本来就是栈的一种应用那么现在来说说后缀表......
  • 已知有三盏灯,LED_1,LED_2,LED_3,每盏灯有两种状态LED_ON,LED_OFF,现有两个函数void init
      #include<stdio.h>#include<string.h>#include<stdlib.h>typedefenum  {    LED_1,    LED_2,    LED_3,  }LED;typedefenum{  LED_ON,  LED_OFF,}LED_CON;voidinit(LEDL){  switch(L)  { ......
  • 执行a包时,怎么调度b包init函数
    在Go中,当一个包被导入时,该包中的init函数会在程序执行开始时自动被调用。但是,直接导入a包时无法保证b包的init函数被调用。如果你希望在导入a包时同时调用b包的init函数,你可以在a包中手动导入b包,这样在a包被导入时,b包的init函数也会被执行。例如:1//a......
  • python中类的__new__方法和__init__方法
    python文章目录python一、python中类的__new__方法和__init__方法二、第三行解释说明instance=super().__new__(cls)三、__init__,__new__返回的是什么?四、debug代码运行中cls,instance,self都是什么东西怎么理解cls是<class'__main__.MyClass'>,instance是<__main__.......
  • robot_sim_demo: Cannot locate rosdep definition for [yocs_cmd_vel_mux]
    提纲1、问题描述2、解决方法3、原因分析1、问题描述下载了ROS-Academy-for-Beginners后,开始用rosdep安装依赖,但是发现执行官方文档提供的依赖安装命令:rosdepinstall--from-pathssrc--ignore-src--rosdistro=kinetic-y,后出现了错误,如下所示:zzl@zzl-virtual-machine:~......
  • Python TypeError: __init__() missing 1 required positional argument 问题
    当我们学完class还未熟练运用,或做题时可能总会遇到这个问题,那我们该怎么解决呢首先我们先创造一个类,如:classfunc:def__init__(self,b2,c1):self.c1=c1self.b2=b2print(b2,c1)在这里我们建立了两个变量:b2,c1,而当我们传参时,可能是只付......
  • #pragma INITCODE
    #pragmaINITCODE//将driverEntry设在分页内存中,当驱动加载成功,此函数在内存中移除。 PAGED_CODE();//当例程所在的中断请求级超过APC_LEVEL时,会产生一个断言,断言会使程序终止。......
  • Spring揭秘:BeanDefinition接口应用场景及实现原理!
    BeanDefinition接口灵活性高,能够描述Bean的全方位信息,使得Spring容器可以智能地进行依赖注入和生命周期管理。同时,它支持多种配置方式,简化了Bean的声明和配置过程,提高了开发效率和可维护性。技术应用场景BeanDefinition接口定义了一个Bean的元数据,它包含了用于创建Bean对......
  • 使用 u-boot 和 rootfs/Initramfs 启动 Raspberry Pi 4
    使用u-boot和rootfs/initramfs启动RaspberryPi4B0.概述这篇文章的目的是了解嵌入式Linux的四个组成部分——工具链、引导加载程序、内核、根文件系统——通过使用最少的代码从头开始启动RaspberryPi4的命令。1.硬件要求用于编译源代码的Linux桌面计算机。......
  • [262144 P]
    262144P题目描述游戏一开始有\(n\)个正整数,\((2<=n<=262144)\),范围在\(1-40\)。在一步中,贝西可以选相邻的两个相同的数,然后合并成一个比原来的大一的数(例如两个7合并成一个8),目标是使得最大的数最大,请帮助Bessie来求最大值思路我们假设所有的数全是\(40\)那么最大可以合成出......