引言
随着低代码的普及,在低代码平台上构建企业级应用逐渐成为生产趋势。同时,随着低代码技术的提升,越来越多的复杂应用在低代码平台中完成。在其研发生命周期中,低代码开发者就会面临多人协作、并行开发、维护多版本的场景。而现有的低代码平台普遍缺乏这一能力或支持较弱,导致对协同开发的成本较高,限制了迭代的效率。
因此我们基于低代码系列相关协议,设计了低代码多分支协同开发的解决方案,以降低协同成本、提高研发效能。
协议原文:https://lowcode-engine.cn/lowcode[1]
低代码引擎官网:https://lowcode-engine.cn/index[2]
本文适合对低代码引擎有基本了解的人,了解低代码引擎的基础协议,并且希望通过文章中得到基于低代码引擎体系的多人协作方案。
为什么要做多人协同
低代码技术在业界已经流行了相当长一段时间了,在阿里内部也有很多低代码平台,其中某平台具有较多的用户量和活跃的中后台应用;在该平台持续的用户调研中,大量用户反馈需要更加优化的协同、多分支能力。“低代码协同开发”问题成为了用户切实的顾虑和痛点。
现在有什么问题
我们可以从下面几个真实的场景中,来感受一下当前的困境:
- 当一个页面的开发任务拆分给了两名同学,就只能一人开发完之后,另外一个同学才能进行开发;
- 当开发的过程中,突然需要修复线上问题,就需要回滚完成修复后,再重头开发新的需求;
- 当多功能并行开发时,就需要复制多份页面,最后再人工进行 schema 合并;
由此我们可以看出来这个低代码平台有三个问题:
- 不支持并行开发。导致开发人员的闲置,限制了开发时长和协同方式。
- 不支持迭代模式。不具备隔离性,无法支持复杂应用生命周期的迭代需求,尤其对于快速迭代升级的业务,导致迭代成本非常高。
- 无法合并修改。复杂、无规范的手动合并流程,只有对协议很熟悉的专业人士才能操作,导致合并和验证成本提高。
问题分析
低代码开发本身的优势就在于“成本低”、“速度快”,不能因为协同方案而导致开发复杂度大幅提高。以此想要解决以上的问题,其实有一些需要考虑的问题:
- 如何“协同”?
在考虑并行开发问题时,其实不应让开发者同时在一个页面里同时操作,而是通过适当的进行拆分解耦;就像在工业生产时,一个机器分解为若干个零件,流水线分别完成零件后再组装成机器。在代码开发时也是如此,那么我们就需要一套类似“零件生产”、“零件组装”的能力,来支持拆分低代码页面。
- 如何实现多版本?
低代码应用的数据都存储在数据库中,怎么在数据库中实现分布式版本控制,维护不同的应用版本。难道要实现一套基于存储低代码数据数据库的 Git吗 ?
- 如何控制开发复杂度?
低代码开发者不同于源码开发,他们本身就不是面向“代码”本身,覆盖的人群也不全都是专业开发人员,怎么才能让低代码开发者熟悉多分支开发的流程呢。总不能附上一份《Git从入门到精通》,强行提高低代码开发的门槛。
怎么做多人协同
这个问题在系列文章的前篇《低代码技术在研发团队的应用模式探讨》中,我们也做出了探讨。
我们的整体策略其实是“刚柔并济”的组合拳,分为了以下两步走:
- 削弱:
80% 的并行开发需求都应该通过拆分颗粒度的方式,来降低耦合度、减少必须多人共同开发同一模块的可能性。可以通过设计应用模块划分、合理拆分组件,尽可能的规避需要多人协作的场景。比如:
- 通过微前端,将大型应用拆分,通过独立发布功能的小应用来构建大型应用;
- 拆分组件:抽象更多业务垂直的能力,区分模块开发。这样同一页面就可以拆分为多个模块,由不同的开发人员开发,也提高了复用性和封装性。
- 硬刚:
在不可避免的情况下,参照源码开发,我们也需要设计一个健壮的分支管理策略,来有效管理开发协作、功能迭代和版本并行,更优雅更高效的解决版本控制和合并问题。也就是:
- 开发者可以从主干上分离出来一个分支进行操作,既不影响主干,分支之间也相互独立、互不影响;
- 当在分支上开发完毕后,可以合并到主干上
如何实现
平台背景
首先介绍下我们这套方案的背景。当前有一款低代码平台,同大部分低代码应用一样,暂时还不能很好的支持协同开发的需求。后续将介绍如何在该平台上应用这套方案设计。
- 研发流程
新建应用后,就可以通过可视化的方式进行研发,包括以拖拽方式对表单页面进行开发,或者对导航、主题色等进行配置。待完成开发后,即可以将应用发布到日常环境进行测试,接着发布线上资源。
这就完成了一个完整的研发周期,待新需求到来后,再开始下一次的应用开发。
当前效果
在系列文章的前篇中,也对研发流程做出了探讨。可见《关于 LowCode&ProCode 混合研发的思考》
前文提到了不想由多分支方案带来过高的复杂度,因此我们在流程设计上,整体保留原有研发流程。通过上文中设计的策略,做出了以下的产品设计:
- 并行开发:支持组件研发
通过支持项目内低代码组件的方式,可以将页面开发需求拆分为组件进行开发,包括:
- 低代码组件 + 物料描述(优先使用)
- 这里低代码组件指的是:通过可视化的拖拽、配置的方式生产的组件,具备与 react 源码组件同等的能力。
- 源码组件 + 物料描述:
- 参考低代码引擎开源项目中提供的组件形式。
这两种组件都在低代码页面中直接使用。待组件分别研发完毕后,既可以在低代码页面做完成集成。这样就可以在不同的组件中进行独立并行研发。
- 迭代管理:多分支模式
开发者在创建应用后,通过创建/选择迭代,在独立的迭代中完成自己的研发内容,包括低代码组件和低代码页面的研发;当在当前迭代上开发完毕后,可以合并到主干上。
下文就多分支模式的技术方案和实现,做出详细的阐述:
技术实现
方案设计
1. 依靠 Git 实现迭代管理
既然有 Git 如此成熟且优质的解决方案,当然是选择站在巨人的肩膀上。我们通过双向转换,将数据库中的元数据,通过出码转为为中间码(react-like 前端可理解的形式)并存储在Git中。使用git 的基础能力,来提供分布式版本控制能力。
2. 简单的分支策略
整体流程上,我们保留了低代码应用的开发习惯,只透出迭代的概念,不过多透出分支、commit、pull、push 等概念,而是将其融入发布流程。开发者不需要手动拉取主干或者提交修改,只需要 work in 自己的迭代中,进行开发、测试和发布。也就是的 分支开发、主干发布 的模式:
- 仅有一条 master 作为主干,所有的分支创建都从 master 复制拉取;
- 发布日常时,需要合并 Master 的修改;
- 发布线上后,分支并入 Master 后删除。
创建应用
会先创建一份应用的数据,保存在数据库中;再创建对应的Git 仓库,同步应用的管理员权限;将Git 仓库的 ProjectId 存储于应用的属性中。
创建迭代
会在数据库中复制一份完整的数据(迭代应用),在迭代的开发过程中,数据都保存在这份【迭代应用】中。同时Git也会从 Master 拉取开发分支,开发分支的名称与【迭代应用】的版本号保持一致,以此作为映射的关联关系。这样各个迭代之间就相互独立、数据隔离。
用户进入应用后,就可以选择不同的迭代进行独立的开发了。
发布日常
- [DBToGit] 应用数据转码,保存到Git分支;[Git] 合并主干,依靠Git进行代码合并;如果有冲突,使用 WebIDE 解决冲突
- [GitToDB] 分支数据转存到迭代应用
- 应用打包 & 构建
转码方案
该流程用于将整个应用的内容转换为指定目录结构的文件并提交至 Gitlab。应用的所有数据都被映射到文件结构中。
页面中的 Schema 部分包含了视图、数据源、页面Js和样式等数据,对数据做出拆分。
页面 Schema 中的组件树部分通过转码转为 JSX+ 语法,更加符合前端开发者的习惯,方便用户完成冲突解决和代码评审。
在 JSX+ 的 DSL 转回组件树原结构时,需要用到抽象语法树,利用 babel 来解析 JSX 文件。再递归遍历语法树,还原回符合《低代码引擎搭建协议规范》的 schema 结构。
发布线上
- 发布线上前检查: 主干是否有更新,是否完成评审等
- 应用打包 & 构建
- [Git] 开发分支合并到 Master
- [DB] 迭代应用覆盖线上应用数据
拓展能力
虽然很多低代码平台底层都是使用低代码引擎和协议栈,但是同时他们也有自己的对于协议的扩展。为了满足不同平台的定制化诉求,此方案需要一定的拓展能力,来适应更多平台的使用诉求。
- 基于《低代码引擎搭建协议规范》的标准协议,我们设计了对应的标准多分支编码器,同时也提供了多种钩子,方面对协议进行拓展。
- 在发布日常和发布线上的服务上,也对应设计定制数据的方式:
dbToGitHook: 供上层平台定制提交到 Git 的数据内;
beforeGitToDbHook: 提供合并了 master 后的 Git 内容,上层平台返回修改后的 Git 结构;不改变git origin 信息,只作为执行转回到数据库的源文件。
可视化多分支协同
以上方案目前已经在企业智能部门的低代码平台开始使用,但目前的方案还只是刚刚 “可用” 状态,依然还存在 “不好用” 的问题。其中最突出的就是 “水土不服” 问题,目前的多分支是参考源码研发体系的多分支玩法设计和建立的,和低代码的使用场景有非常多不契合的点:
- 看不懂:普遍反馈看不懂冲突解决困难,不能理解 DSL 中的属性;
- 割裂感:从低代码平台跳转到 WebIDE 去编辑代码,不符合低代码操作直觉;
- 不可控:自动合并后发布时,对于有什么改动、合并结果没有把握;
所以我们将会继续建设好用的多分支解决方案,建立契合低代码心智的多分支研发体验,提供统一的“可视化”解决方案,彻底解决这个问题。包括:
- 可视化 Diff:使用可视化的 Diff ,帮助用户确认发布线上前的改动点;
- 可视化 CR:评审者可以可视化得看到开发者所有的修改,更好的做上线前的判断;
- 可视化 Merge:可以通过点选选择保留的冲突。
其中,我们目前对于 可视化 Diff& CR 的产品设计如下:
- 能够查看该开发分支 和线上主分支的差异(即改动点)
- 能够清晰的、可视化的展示需要关注的改动
整体设计方案,是根据转化的 DSL 内容计算出变更的信息,通过可视化得呈现出改迭代的所有改动点;而发生合并冲突时,列出冲突的信息让开发者可以通过点选操作,来保留所需的改动内容。