Mometa 低码前端编辑器原理学习

notion image

实现原理

1. React 产物构建(/bundler.html)

React 产物是 Mometa 编辑器当前编辑的 React 代码

构建方式

构建时使用 babel/plugin-react 插件构建时注入代码元数据
引入 babel/plugin-react 插件:
构建时使用 Mometa 编辑器插件(MometaEditorPlugin
引入插件:

实现原理

babel/plugin-react 原理(注入 Empty Placeholder 略)
源代码:
注入元数据后的代码:
元数据类型定义

2. 构建编辑器(/index.html)和 Mometa 运行时(mometa)

  • 编辑器是在可视化编辑时的外壳
    • Mometa 运行时用于解析 React 打包后的产物和用于通信的,所以会在 React 产物打包的时候使用 MometaEditorPlugin 注入 Mometa 运行时

      构建方式

      构建 Mometa 运行时
      构建编辑器

      实现原理

      Mometa 运行时产物有两个:
      1. Entry 产物
          • 目的一:读取 babel/plugin-react 注入的__mometa元数据,并转到 react element 的 source 元数据中
            • 目的二:为 iframe 注入通信、路由、渲染能力
          1. Empty Placeholder 产物
              • 单独打包的 React 占位组件,显示为空视图元素
                • React 产物 打包的情况下使用 babel/plugin-react 注入 Empty Placeholder
              编辑器原理(packages/editor/src/editor.ts)
              • UI 区渲染
                • 通过 createClientConnection 建立本地 Server 的 SSE 连接,接收如下素材相关信息:
                  • set-materials
                    • materials-loading
                      • set-materials-client-render
                        • error
                        • 通过 ApiServerPack 建立调用本地 API 能力的封装,并允许传给字 Iframe 使用,相关能力如下:
                          • up
                            • down
                              • del
                                • copy
                                  • insert-asset
                                    • move-dom

                                    3. MometaEditorPlugin 原理

                                    React 产物打包的时候会使用 MometaEditorPlugin ,主要功能如下:
                                    拷贝编辑器代码到指定目录,并且在编辑器的 index.html 中注入 editorConfig
                                    注入 Mometa 运行时 相关代码
                                    注入环境变量
                                    注入 React 运行时ReactRefreshWebpackPlugin
                                    注入的 React 运行时会在 Mometa 运行时中使用,主要是用户读取 React 组件 props 上的 __mometa 数据,并挂在到 fiber 中
                                    创建本地服务
                                    • 创建 Http 服务,并且监听 /submit-op(文件文本操作)、/open-editor(打开编辑器) 路由
                                      • 创建EventStream,并在素材构建的时候发送 materials-loading 消息
                                        • 实现客户端渲染热更新
                                          基于本地服务实现物料热更新逻辑
                                          物料热更新有两种热更新模式:服务端序列化数据热更新 或 客户端渲染热更新(开启 experimentalMaterialsClientRender)
                                          • 服务端序列化数据热更新
                                            • 物料文件的改动监听都在服务端 Node.js 内自己处理,首次或一旦检测到改动,则推送最新数据至浏览器进行更新,热更新 Node.js 实现见 https://github.com/imcuttle/hot-module-require ,返回为可序列化的物料数据。
                                          • 客户端渲染热更新
                                            • 物料文件的改动监听交由 webpack,首次或一旦检测到改动,则触发 webpack 编译(第一次子编译),Node.js VM 环境执行编译后代码,得到 materials 配置;通过 materials 配置计算得到前端可执行代码,进行 webpack 编译(第二次子编译);所以使用该方式可以达到物料动态预览的效果
                                            • webpack 在编译时读取 mometa-material 配置并使用 node vm 运行并获取配置的数据
                                              • 通过 EventStream 发送给浏览器内,刷新资源配置
                                                • 添加并编译 mometa-material 配置文件

                                                Reference


                                                © Jiyu Shao 2018 - 2025