You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
代码不能凭空出现,页面的关键信息点不能少,比如有哪些字段、字段类型、字段中文名、字段间的关系、页面交互信息等等,可以统称为:描述完整页面的最小信息集。这个“最小信息集”从哪来?最简单的方案是给个配置平台,让用户手动录入,再生成页面。但是现代 IDE 环境越来越智能,代码智能提示,文本替换,相比用户手动录入信息,不见得直接写胶水代码体验会更差好,或者更慢。如果一个团队的研发流程比较成熟,肯定会有这两个文档:
问题
B 端系统有很多“相似”的样板代码(胶水代码),但是很多细节又不一样,例如一个常规的列表页面:
....
其他详情页、表单页面都有类似的情况。每天写大量这种无聊的代码,简直是浪费生命。
问题分析
这种内部细节差异非常多的场景,不好对其进行抽象,每种场景的问题域还不一样,列表页有列表页的难题,表单页有表单页的难题。强行沉淀为业务组件,会面临配置多、不方便后续扩展等问题。相对比,较好的方向是,能通过某种手段直接生成类似手写的代码,这样既避免写大量胶水代码的苦力活,又能让开发用他们之前熟悉的开发模式,在生成代码基础上继续扩展高级功能。
代码不能凭空出现,页面的关键信息点不能少,比如有哪些字段、字段类型、字段中文名、字段间的关系、页面交互信息等等,可以统称为:描述完整页面的最小信息集。这个“最小信息集”从哪来?最简单的方案是给个配置平台,让用户手动录入,再生成页面。但是现代 IDE 环境越来越智能,代码智能提示,文本替换,相比用户手动录入信息,不见得直接写胶水代码体验会更差好,或者更慢。如果一个团队的研发流程比较成熟,肯定会有这两个文档:
通过这两个文档,能直接分析出很多“最小信息集”里面的信息,从而需要用户录入的信息就很少了,在部分常规的场景下,甚至不需要再录入。导入接口文档,即直接生成页面。类似于下面这个 demo:
设计
要实现上述系统,可以采用如下架构,以提升系统的灵活性和可扩展性。
Page Schema
编译生成代码。API Schema
的格式,可根据不同 UI 库实现不同 Adaptor 生成Page Schema
。API Schema
。Compiler 模块
Compiler 生成的代码分为两部分:可复用的公共代码和不可复用的组件代码。在生成公共代码之前,Compiler 会先扫描原项目是否已经生成过了,假设现在 Page Schema 声明依赖了
utils.js
文件下的pick
函数,Compiler 会先检测utils.js
是否含有pick
函数,如果有则跳过,没有则注入一个新的pick
函数。对于不可复用的组件代码(.vue
文件),Compliler 每次都会生成新的进行覆盖。因此在对不可复用代码进行二次修改后不可再生成,否则会直接覆盖。关键数据类型定义如下:Page Schema
的类型定义:ContainerComponent[]
CSS
JSCode[]
DependentResource[]
容器组件
ContainerComponent
可以是一个页面,或者一个组件。例如一个单文件组件SFCComponent
:string
string
Component[]
SetupCode[]
CSS
ComponentPropDefinition[]
string[]
普通组件
Component
的类型定义,CSS 类型定义,如果输出的文件的是个文件,则需要对已有 css 文件进行 AST 语法解析,增量修改 css 内容,不能直接覆盖,方便对代码的二次修改。
css
、less
string
string
string
boolean
JSCode 类型定义,描述依赖的 js 代码,如果输出的文件的是个文件,则需要对已有 js 文件进行 AST 语法解析,按需修改 js 文件代码,不能直接覆盖,方便对代码的二次修改。
string
string
string
DependentResource 类型定义,描述页面的外部依赖,修改
package.json
文件string
string
Adaptor 模块
Adaptor 接收的输入为
API Schema
,结合适配器里面的 UI 信心和部分胶水代码,生成Page Schema
。举个生成表单的例子:API Schema 结构如下:
string
string
object
Field[]
Field[]
Field[]
Field 字段类型定义如下:
string
string
string
string
boolean
string
Option[]
string[]
RenderComponent
API Schema
Client 模块
Client 模块主要包含三块功能:
分析用户选择的页面“主接口”,推导生成初步“最小信息集合”
除了静态页面,其他B端系统至少有一个“主接口”,例如表单页面的新增/修改接口,列表页面的列表查询接口。用列表页举例:
当用户选了一个列表查询接口之后,大概步骤包含(根据场景可以丰富更多的策略,以提升识别能力):
解析需求文档,完善“最小信息集”
接口文档有时候不够详细,字段中文缺失,或者描述错误,字段格式缺失。还有些信息是接口文档不具备的,例如字段的一些校验信息,枚举值的中文信息。这些可以从需求文档中提取,填充到“最小信息集”,以减少用户的配置成本。
对 “最小信息集” 的增/删/改
这个就是一些前端页面的基本配置了,提供一个配置界面即可。
Server 模块
由于我是个前端开发,大部分前端能做的,自然而然就放到前端去了,给服务端这块分配的功能相对弱很多,包含配置管理和接口文档请求就差不多了,按实际功能划分,接口分析放到服务端感觉合适一点,这样前端就纯粹一些。
最后附上一个简单的实现传送门
The text was updated successfully, but these errors were encountered: