elpis全栈应用框架-总结

6 阅读11分钟

elpis是什么?解决了什么问题?

elpis是一个涵盖服务器端和前端的企业级应用框架,旨在解决目前企业中常见的crud工作中的重复部分,将其规范化和配置化,减少重复工作的生产。同时也能够让纯前端的程序员能够接触到服务器端的开发流程,更好的了解整体的一个应用流程,扩展更高的价值。最终效果即一份配置生成一套系统。

整体的架构框架如下,我将eplis分为三大部分,BFF层(基于nodejs去实现的一个服务器内核引擎,即BFF),展示层(依靠DSL配置化内容去渲染实现对应的组件内容和功能),数据层。

image.png

里程碑一:基于 node 实现服务器内核引擎

服务器端:我们命名为elpis-Core, 借鉴eggjs, 基于nodejs结合koa我们来实现一个BFF层的功能。(接入层,业务层,服务层)

1.洋葱圈模型:接入层开始 -> 接触到各种各样的中间件 -> 接触到业务层 -> 离开中间件 -> 返回给客户端 我的理解就是浏览器发送一个请求到服务器,服务器会进行各种处理,对数据进行操作,获取我们需要的数据,返回到前端进行数据渲染。这部分我的理解就是当前后端分离中后端的任务!负责封装接口,兜底抛错,权限鉴定,然后查表,进行增删改查的操作。

image.png 2.约定配置原则:将每个文件夹的命名和实现的功能都约定好,之后所有的配置都按照我的配置来。也就是七大loader,controller,service config,extend,router,router-schema,middleware,分别就是执行读取我们的实际文件,将其挂载在我们的koa实例上来进行使用。

里程碑二:基于 webpack5 实现工程化建设

首先要先了解为什么我们需要进行工程化建设---> 为了将我们的这些个文件打包成为浏览器能够正确识别的文件,减少浏览器读取加载文件的负荷,加快运行速度。以及在开发环境的提效开发。

image.png 下面基于生产环境和开发环境进行一下概述:

生产环境:注重打包效率,尽我们所能的去减少浏览器读取和加载我们文件的成本。所以在生产环境下,我们就会做一些代码压缩,代码分割,tree-shaking 剔除无用代码,多线程打包等这些操作。

开发环境:注重我们的开发效率,也就是热更新,我们肯定不希望我们改一个字段就要重新手动执行一遍打包重启的这个过程,所以引入了热更新。热更新的过程就是 监听文件修改 -> 识别模块变更 -> 通知浏览器 -> 浏览器进行局部更新。webpack提供了两个核心的中间件来帮助我们实现热更新,devMiddleware(文件监控和编译),hotMiddleware(与浏览器通信)

里程碑3:基于 vue3 完成领域模型架构建设

什么是领域模型架构DDD?

DDD(Domain-Driven Design),是一种模型驱动设计的方法,通过模型直接反应实际软件的结构,以模型形成团队的规范,去减少我们所需要维护的功能代码,更方便扩展。我个人的理解就是,生成一套流程文档,类似于 antd pro 这样的集成ui组件库,我们遵循他的配置,实际上只要关注在哪里引用,不需要去关注他是怎么实现的,同时也提供了我们自主封装的能力。不过我们这是整体配置,随着我们后续的不断维护,这个项目能够变的能够直接适配大多数的项目。

架构设计 image.png 如图,我们的设计思考能够支持不同的配置文件来生成不同的系统,但是配置文件的结构是一致的,然后通过模板配置解析将配置处理成我们需要的格式渲染到我们的模板页面,最终渲染展示不同的系统。

基于大部分的后台管理系统配置我们可以将我们自己的模板页开发分为这几块:

页面功能划分

  • 横向导航区域(header-container)
  • 纵向导航区域(sider-container)
  • 内容展示区域(container)

内容展示区域有三种类型

  • -嵌套内容 iframe-view,
  • -自定义内容 custom-view,
  • -模板内容 schema-view,

模板内容又可以细致划分成为

  • -表单操作区 search-panel - > schema-search-bar
  • -表单内容区 table-panel -> shcema-table-view

划分好之后我们对应的实现对应的功能

image.png

整体的设计就是这样,还有一点很重要就是在设计模板页面的时候,应该要以模块来划分,而不是以组件维度来划分,只是单纯的将一个页面拆分成为各个小组件去渲染,分模块,再由模块下去引对应的组件,这样更方便管理,更清除的了解页面设计,以及后续如果有某个模块需要什么大变动也能够直接对文件夹模块去进行处理,降低了维护的成本和阅读成本。

里程碑4:基于 vue3 完成动态组件渲染

我们在后台管理的开发过程中,我们其实是能够感知到,列表的字段和搜索字段以及新增编辑的字段其实有一定程度上都是重复的,那么我们在设计动态组件的配置的时候也要考虑到这一点,就是我们只维护一套字段,然后对这些字段去进行对应模块的展示,例如现在有一个字段 商品名称 shopName,那么我在搜索和展示,新增编辑的时候都有使用到,如果按照基础的配置就是,在每个模块都配置一个shopName字段然后对其进行具体的操作,这样其实太重复了。所以我们在这边的设计是如此

image.png

效果大概是这样,所有的动态组件渲染都遵循 schema config 配置原则。

image.png

里程碑5:完成框架 npm 包抽象封装并发布

在当我们实现了这一个根据配置来模板化的这样的一个项目的时候,到最后一步,抽离成为一个npm架包。 我们希望我们真正实现的是一个框架,而不单单是一个项目。 那么为了将其抽象封装架构,我们需要进行以下的操作:

1.首先需要支持业务方的启动和打包。

module.exports = {
  /**
   * 服务端基础
   */
  Controller: {
    Base: require('./app/controller/base.js')
  },
  
  Service: {
    Base: require('./app/service/base.js')
  },
  /**
   * 编辑构建前端工厂
   * @params env 环境变量 dev/prod
   */
  frontendBuild(env) {
    if (env === "local") {
      FEBuildDev();
    } else if (env === "production") {
      FEBuildProd();
    }
  },

  /**
   * 启动 elpis
   * @param {*} 项目相关配置
   * @returns
   */
  serverStart(options = {}) {
    const app = ElpisCore.start(options);
    return app;
  },
};

2.将所有的 loader 和配置文件进行改写,首先默认加载我们elpis中的文件,但是还能够支持扩展业务方的配置文件,这点很重要!这样能够大大的加强我们框架的扩展性,能够支持更多的应用开发场景和个性化处理。当然,业务方在配置的时候要保持和遵循我们的规则。

### 自定义页面扩展
* 在 `app/pages/` 目录下写入口 entry.xxx.js

### dashboard / custom-view 自定义页面扩展
* 在 `app/pages/dashboard/xxxx` 下写页面

### dashboard / schema-view /components 动态组件扩展
1.`app/pages/dashboard/complex-view/schema-view/components` 下写组件
2. 配置到 `app/pages/dashboard/complex-view/schema-view/components/component-config.js`

### schema-form 控件扩展
1.`app/pages/widgets/schema-form/complex-view` 下写控件
2. 配置到 `app/widgets/schema-view/form-item-config.js`

### schema-search-bar 控件扩展
1.`app/pages/widgets/schema-search-bar/complex-view` 下写控件
2. 配置到 `app/widgets/schema-search-bar/search-item-config.js`

总结 和 思考

上述就是整体的一个关于elpis的项目介绍和我个人对项目的一些理解。 在通过完成这个项目后

首先是对服务器的开发有了一定程度的理解,知道了服务器开发是在做什么事情,也手动的去进行了服务器端的简单开发。

对整体项目的架构设计也从0-1去做了一遍,首先是架构思维上有了一定程度的概念和积累,也学习到了很多好的代码开发思路和习惯,有了地基,而不再是做一些crud的开发业务。

我认为这个项目后续可以扩展功能主要从几个方面来考虑(配置更简单,功能更丰富)

配置更简单:

  1. 实现一个模板可视化预览配置页面去配置一些比较常用的模板,没有什么比视图更清晰的让使用者上手了,而且功能还可以快速支持,他们只需要依靠我们提供的model去在做一些简单的个性化配置即可,可以增加一个这个功能页面。(我的做法是,我们配置好几个展示的model自己获取,然后通过在展示页面我们去监听model切换,然后去触发我们的整一个schema-view的组件,对应展示出来。整体上其实我们不需要去重新再调用对面的部分组件,直接引入整体的一个schema-view组件,这样如果我们schema-view组件后续有新功能维护,这边demo展示也能够有所反馈)或者也可以尝试用react flow 类似的这样的流程节点类的第三方库 去渲染生成一个我们自己项目的全流程图,把我们的项目结构以流程图形式渲染。可以编辑任意节点然后生成。

  2. 可以尝试结合AI,我们描述根据模块来描述对应的功能和需求,直接由AI去生成我们的model模板文件。(因为AI流我目前只是稍微了解了一下,这个算是我的设想,我的想法是由ai读取我们的文件配置,然后使用者会根据模块去对ai进行提示词的输入,ai转化这些提示词匹配我们的model结构且他只负责去处理我们的model文件,然后生成model文件。)

    关于ai这个我甚至想是不是可以直接根据我们的vue版本来生成一个react版本,有ai插件是能够根据你的目标代码去转化成其他语言的代码,可以接入类似这样的,或者去实现一个这样的功能。这样如果业务方有react框架要求,我们也是能够支持的。但是ai这块我目前了解的不是很多,只能提出几个我认为是可行的方案,后续研究下怎么把这个东西落地下来。

功能更丰富:

  1. 根据ui库组件,封装更多的更常用的一些动态组件库,比如地图选址,结合高德地图开发API实现地图选址。省市区三级级联,这样可以更快速的支持物流类的项目需求。或者支持主题等的一键切换,国际化配置等等一些个性化的配置。
  2. 我们的新增编辑和详情查看页面,也能支持列表的渲染,包括button的一些操作。这个对应的也加入一个配置就可以实现。
  3. 可以将JS改为TS,在开发过程中就对组件属性进行约束,不要等到上线后页面报错,可以有效减少这类的问题,提高稳定性。
  4. 对接口请求可以设置一个中断请求的时候,如果请求超过10秒就中断请求,返回抛错告知用户重新尝试。
  5. 我们可以做一个我们自己项目的官网,也可以生成我们的专属文档,更详细的介绍是怎么操作的,后续也可以推出别的项目一起放在上面。