DSL:以极其高效的方式描述特定领域的对象、规则和运行方式的语言。
以上为引用的 dsl 概念,那么我们要如何利用这样的方式,来达成我们的目的:沉淀大多数的重复通用工作,且提供灵活的可扩展空间呢?
在学习过程中,我们可以遵循 JSON-SCHEMA 规范来基于模板设计 DSL,总体涉及大纲如下:
根据 JSON-SCHEMA 规范我们可以实现一份自己制定的 dashboard-model.js 模板数据结构。
JSON Schema 本身是用 JSON 编写的。它是数据本身,而不是计算机程序。它只是一种用于"描述其他数据结构"的声明性格式。
在此基础上,我们就可以创建自己预计的领域模型,并且在领域模型的基础上派生出不同的 project (项目)。
大概过程我们可以定义详细的 model 模型文件配置(领域模型 ) 以及 项目文件配置,将各个项目所通用的配置抽离到 model 层领域模型,沉淀重复内容,提供扩展能力,即通过以 DSL 为模板,设计领域模型以及扩展项目配置并且通过解析器将前者继承到后者,解析的过程无非是读取 js 配置文件,继承过程利用 lodash 库的 mergeWith 方法,核心标识为 key 值即可。
这里可以详细说明一下解析器的执行过程: 获取模型目录下所有的 js 文件目录,通过判断目录是否含有 project 字符串来判断是领域模型 还是项目配置。
如果为 project 则将读取出的文件内容存放于以下部分,其中 modelItem.project 是一个数组,存放不同的项目内容,核心代码如下:
js
modelItem.project[projectKey] = require(path.resolve(file));
modelItem.project[projectKey].key = projectKey; // 注入 projectKey
modelItem.project[projectKey].modelKey = modelKey; // 注入 modelKey;
如果为 model 则读取其中内容存放于以下部分:
js
modelItem.model = require(path.resolve(file));</br>
modelItem.model.key = modelKey; // 注入 modelKey`
最终我们可以得到以下数据:

后续我们针对不同的页面需求,还可以通过组件解析器、api解析器、表单解析器来进一步处理数据。
到此即完成根据领域模型配置以及项目配置得到完整站点的整个过程。
接下来我们看看如何不断的丰富模型内容:
根据模型的 menu 属性来实现菜单,这里的菜单不只是菜单内容,还包括点击菜单后需要实现的页面内容是什么样的,因为我们除了设置一些菜单的基础属性 ( key、name、menuType)还会配置对应的 menuType 对应的 xxxConfig 配置项( siderConfig、iframeConfig、customConfig、schemaConfig )等内容。
一、当 menuType 为 group 的时候,我们制定 subMenu 配置项,其值同样为进行 menu 配置,也就是递归过程。
二、当 menuType 为 iframe 的时候,我们制定 iframeConfig 配置项,创建 iframe 指定地址。
三、当 menuType 为 custom 的时候,我们制定 customConfig 配置项,其中配置路由会指向一个为用户提供的可自主扩展的空白组件,待用户自主开发,提供扩展能力。
四、当 menuType 为 iframe 的时候,我们制定 iframeConfig 配置项,路由会指向一个为用户提供的地址来嵌入到 menu 对应的菜单内容区域,可用于微服务、嵌入自己的页面等情况,提供扩展能力。

五、当 menuType 为 schema 的时候,我们制定 schemaConfig 配置项,该配置项尤为重要,主要涉及表单的配置,包括搜索栏以及表单区域。
首先我们可以讨论开发表格组件的时候一些背景情况:
1、第一种情况是直接上手编写表格,表单,搜索框等内容,这样如果多个地方需要使用到类似组件,那么我们会开发重复内容。
2、第二种是通过配置解析器,或者通过写个函数通过参数,或者也就是说封装一个较为通用灵活的组件,通过传递参数抛出事件等形式来实现表单等功能,平常工作中确实我自己使用这种方式最多,但是难免会因为不同需求的差异带来的兼容性问题导致额外的负担。
并且由于不同的客户或者产品会引发不同的需求,可能会导致原本封装的组件并不适用,甚至需要另外再写一个组件。
3、因此则衍生了第三种,通过 DSL 设计模型的配置来通过一份数据来描述出关于目标模块中的各个部分,包括( 搜索栏,表单,表单按钮等以及对应的api )然后通过解析器来获取数据 以及解析预处理数据 以及 (组件解析器、api 解析器、表单解析器等等)
在学习过程中,我们编写了一些配置项:
其中 tableOption 意为该字段在表格中的一些配置(包括样式等)
其中与 schema 平级的 tableConfig 描述表格的具体功能(包括 headerButtons 及其事件名称等) 以及 rowButtons。
接下来如果 menu 的 moduleType 为 sider 那么我们就会再在对应的 siderConfig 中来获取剩下的侧边栏的 menu 配置项。
接下来暂时对上述所有的关于 DSL 领域模型架构建设进行总结:
可扩展点:
1、在 dashboard 这个目录下,实际上实现的是一个模板引擎,其中 dashboard-model.js 这个模板可以扩展,实现各种各样的模板
2、moduleType 可扩展,例如可以根据 schema 的设计理念来实现更多的 schema1、2、3
3、searchbar 区域我们可以实现多个动态组件,传递的实际上就是对应的
js
`schema.properties.xxxOption 中的配置内容
// 由于我们在 schema hooks 下配置了
// 处理 comName Option
dtoProps = Object.assign({}, dtoProps, { option: props[`\${comName}Option`] }); dtoSchema.properties[key] = dtoProps;
// 因此使用的时候只需要使用 schemaItem.option 即可拿到对应字段的配置,然后通过字段 comType 来查找对应的动态组件`
4、各类组件也可进行拓展( 弹窗、抽屉、表单等。。。)
5、表格操作按钮也可拓展 tableConfig
6、customView 提供扩展自定义组件
7、iframeView 提供扩展自定义 iframe
8、新的领域模型与项目
9、公用组件库等等
核心即为,以一份模板数据,通过模板引擎,解析 DSL ,沉淀通用功能,扩展灵活部分生成整个站点。