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

实现原理
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 运行时
产物有两个:
- Entry 产物
- 目的一:读取
babel/plugin-react
注入的__mometa
元数据,并转到 react element 的 source 元数据中 - 目的二:为 iframe 注入通信、路由、渲染能力
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 在编译时读取
mometa-material 配置
并使用node vm
运行并获取配置的数据 - 通过
EventStream
发送给浏览器内,刷新资源配置 - 添加并编译 mometa-material 配置文件
物料文件的改动监听交由 webpack,首次或一旦检测到改动,则触发 webpack 编译(第一次子编译),Node.js VM 环境执行编译后代码,得到 materials 配置;通过 materials 配置计算得到前端可执行代码,进行 webpack 编译(第二次子编译);所以使用该方式可以达到物料动态预览的效果