首发自 语雀文档@blueju
前言
渲染引擎,一般来说我认为可以这么解释:将物料拖拽到设计器画布后,将其渲染成真实的组件的一种机制。
接下来将从代码层面由外到里地解读 h5-dooring 的渲染引擎。
SourceBox
SourceBox 组件是一个包含了工具栏、右键菜单、物料栏、画布、属性栏的大组件,由于渲染引擎所在的画布内的逻辑很多,便将其作为独立组件,名为 ViewRender。
只需要将关键数据作为属性传入即可完成渲染,属性名为 pointData,直译较为奇怪,暂且可理解为原子数据,记录了画布上所有组件信息。
ViewRender 组件还可传入拖拽、改变画布大小等一些修改 pointData 的 API 方法,无非是,此处便不做延展叙述了。
ViewRender
在这一层,有了些渲染引擎的端倪——布局处理(采用的是作者所说的基于 grid 的智能网格布局系统)
对原子数据 pointData 进行归类处理,划分出对布局有特殊要求的组件:固定组件、导航组件、头部组件、其他组件,在智能网格系统组件 GridLayout 的包裹下,使用 DynamicEngine 对以上组件进行分类加载,只需要将要渲染组件的信息作为属性传入即可。
在提供的商业版中是有对原子数据 pointData 进行归类处理的,但是开源版中同文件中并未发现,可能转移到别的地方了。
DynamicEngine
动态导入引擎,或者应该说是按需加载引擎,一个 Umi 提供的可以将按需加载方法封装为可按需加载组件的异步组件,封装了使用一个异步组件需要做的状态维护工作,开发者可以更专注于自己的业务组件开发,而不必关心 code spliting、async module loading 等等技术细节。
组件除了从布局维度上进行分类处理以外,还从组件场景维度上进行分类处理,根据按类别从不同的目录使用动态 import 方法引入组件。
接下来,就是正常像封装组件一般操作 components 目录下的组件了,将设计器右侧的属性栏与 components 目录下的组件属性关联起来,这一块并不难,只是 NGFED 的组件众多,需要做较多的定制化属性关联操作,届时另外做一篇进行解读。
总体下来,还是比较简单的,只是要能想到使用这些作为渲染引擎的一种实现方式,需要对 webpack 和 JS 模块化比较熟悉。
对比后发现,虽然所在目录不同,但此块代码开源版与商业版并无不同。 如果还是有些不懂的,可去了解一下 webpack 的 dynamic import
思考
在设计器画布中的渲染引擎,可能是考虑到频繁操作会导致频繁渲染,所以采用 dynamic + import() 的异步动态导入组件的方式进行渲染,而不是采用 JSON Schema 实时解析转为(JSX 组件或 JS)的方式,在设计器画布场景,使用这种方式可以理解。
了解设计器的机制和渲染原理后,我们可以更快速地进行组件二次开发,着手将我们自己的组件库 ngfed 进行物料化。
但涉及到出码时,目前的方式不太适用,无法导出符合我们团队的脚手架规范、可二次开发的代码。但可以根据设计规则解析 JSON Schema 转换为源码,这块需要涉及到更底层的 AST 语法树解析,这一点也是得到了作者的论证和支持。