大型前端应用如何做系统融合?
1. 背景介绍
1.1. 业务介绍
A平台与B平台同属于同一系统链路上,前者主要致力于为用户提供注册入驻服务,后者则专注于提供具体业务操作服务。两者皆为运营人员所依赖的在线管理工具。
1.2. 现状分析
目前这两个平台服务于同一业务方,且B应用的页面已经100%嵌入到了A应用的平台上,除此以外目前存在系统上及体验上的痛点如下:
所以当时我们考虑既然服务于同一业务方是否能在代码层面上将两个平台进行融合,通过系统的融合来达到优化用户体验以及降本增效的效果呢?
2. 成果展示
平台融合后,主要的优化点体现在以下四方面:
优化前(跳转单个页面白屏时间达2998ms左右):
优化后(跳转单个页面白屏时间800ms左右):
3. 具体措施
3.1. 方案调研
3.1.1. 部署方式
3.1.2. 代码仓库整合
3.1.3. 项目框架
3.1.3. 系统权限
3.2. 架构设计
为了让用户融合无体验差别,两个平台的用户继续使用各自的域名进行访问,融合后的项目可以自动识别当前环境,加载对应的内容;保证融合前后用户查看的内容是一致的;
3.3. 具体方案
3.3.1. 目录结构设计
针对融合,我们首先考虑的是融合后如何防止文件冲突,减少融合的复杂度,降低出问题的概率。保证两个系统能正常运行;拆分逻辑分以下三个方面:
两个系统涉及到几十个文件,经过分析,我们将其拆分成以下几部分内容:【页面文件、公共组件文件、mock文件、AxPI接口文件、基础请求封装文件、路由组件文件、Store文件、公共样式文件、公共方法组件、mainjs文件、index.html文件】
2. 结构整合与差异化处理
由于两个项目的结构相似,我们可以针对各个部分进行整合。整体的思路是,对于差异比较大的文件,建立两个独立的文件夹,分别包含系统A和系统B的内容;然后通过一个index文件,识别到当前的运行环境是系统A还是系统B,再分别加载对应的内容;
3. 内容融合与冲突解决
针对差异比较小或者无差异的文件,我们将文件内容进行融合。对于冲突的内容,我们进行了手动修改,并对全局引用部分进行同步修改;
├── root
│ ├── mocks
│ ├── public
│ ├── src
│ │ ├── api
│ │ │ ├── apiA // 存储 A 业务请求接口
│ │ │ ├── apiB // 存储 B 业务请求接口
│ │ │ ├── apiC // 存储 C 业务请求接口
│ │ │ ├── baseHttp.js // 封装基础请求
│ │ │ ├── ARequest.js // A业务的公共处理,请求header和响应code码等处理
│ │ │ ├── BRequest.js // B业务的公共处理,请求header和响应code码等处理
│ │ │ ├── CRequest.js // C业务的公共处理,请求header和响应code码等处理
│ │ │ ├── DRequest.js // D业务的公共处理,请求header和响应code码等处理
│ │ ├── assets
│ │ │ ├── icons // icon内容
│ │ ├── common
│ │ │ ├── config
│ │ │ ├── styles // 一些公共的样式
│ │ ├── components // 公共组件
│ │ ├── directive // 自定义指令
│ │ ├── layout //公共布局
│ │ ├── router
│ │ │ ├── a.js // 对应a应用
│ │ │ ├── b.js // 对应b应用
│ │ │ ├── c.js // 对应c应用
│ │ │ ├── index.js
│ │ ├── store
│ │ │ ├── modules
│ │ │ ├── getters.js
│ │ │ ├── index.js
│ │ ├── utils
│ │ ├── views
│ │ │ ├── a // a 业务文件
│ │ │ ├── b // b 业务文件
│ │ │ ├── c // c 业务文件
│ │ ├── main.js
│ │ └── App.vue
│ ├── env
│ ├── package.json
3.3.2. 应用类型判断
应用类型判断是我们重要的一环,是我们识别环境的基础,当用户通过不同的域名访问到应用的时候,前端维护一个映射表,不同的域名代表不同的应用;在main.js文件中会在第一时间执行判断识别;
let APPLICATION_TYPE = 'a'
let host = window.location.host;
// 维护域名列表,包含测试和线上环境
const A_HOST = ['a.com','a_pre.com']
const B_HOST = []
const C_HOST = []
const D_HOST = []
if(A_HOST.includes(host)){
APPLICATION_TYPE = 'a'
}else if(B_HOST.includes(host)){
APPLICATION_TYPE = 'b'
}else if(C_HOST.includes(host)){
APPLICATION_TYPE = 'c'
}else if(