大型前端应用如何做系统融合?

京东云开发者
• 阅读 301

1. 背景介绍

1.1. 业务介绍

A平台与B平台同属于同一系统链路上,前者主要致力于为用户提供注册入驻服务,后者则专注于提供具体业务操作服务。两者皆为运营人员所依赖的在线管理工具。

1.2. 现状分析

目前这两个平台服务于同一业务方,且B应用的页面已经100%嵌入到了A应用的平台上,除此以外目前存在系统上及体验上的痛点如下:



大型前端应用如何做系统融合?



所以当时我们考虑既然服务于同一业务方是否能在代码层面上将两个平台进行融合,通过系统的融合来达到优化用户体验以及降本增效的效果呢?

2. ****成果展示

平台融合后,主要的优化点体现在以下四方面:



大型前端应用如何做系统融合?



优化前(跳转单个页面白屏时间达2998ms左右):



大型前端应用如何做系统融合?



优化后(跳转单个页面白屏时间800ms左右):



大型前端应用如何做系统融合?



3. 具体措施

3.1. 方案调研

3.1.1. 部署方式

•部署优化:A应用前后端合部署,现计划分离前端独立部署;

•资源节约:经行云部署平台调研,拟采用混合部署策略,将A应用与B应用前端静态资源集中部署于一组容器,以优化资源利用;



大型前端应用如何做系统融合?



3.1.2. 代码仓库整合

•A应用的三个项目与后端共享一个代码仓库,采用统一的编码标准;而B应用则使用独立的代码仓库,需从中分离出前端代码,并确保分离过程不影响现有配置;

3.1.3. 项目框架

•4个项目的技术选型框架都为vue2,依赖项略有不同;

3.1.3. 系统权限

•A应用和B应用为erp登录;

3.2. 架构设计

为了让用户融合无体验差别,两个平台的用户继续使用各自的域名进行访问,融合后的项目可以自动识别当前环境,加载对应的内容;保证融合前后用户查看的内容是一致的;



大型前端应用如何做系统融合?



3.3. 具体方案

3.3.1. 目录结构设计

针对融合,我们首先考虑的是融合后如何防止文件冲突,减少融合的复杂度,降低出问题的概率。保证两个系统能正常运行;拆分逻辑分以下三个方面:

1.文件拆分与分类

两个系统涉及到几十个文件,经过分析,我们将其拆分成以下几部分内容:【页面文件、公共组件文件、mock文件、AxPI接口文件、基础请求封装文件、路由组件文件、Store文件、公共样式文件、公共方法组件、mainjs文件、index.html文件】

  1. 结构整合与差异化处理

由于两个项目的结构相似,我们可以针对各个部分进行整合。整体的思路是,对于差异比较大的文件,建立两个独立的文件夹,分别包含系统A和系统B的内容;然后通过一个index文件,识别到当前的运行环境是系统A还是系统B,再分别加载对应的内容;

  1. 内容融合与冲突解决

针对差异比较小或者无差异的文件,我们将文件内容进行融合。对于冲突的内容,我们进行了手动修改,并对全局引用部分进行同步修改;

├── 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(D_HOST.includes(host)){
    APPLICATION_TYPE = 'd'
}
// 挂载全局
window._APPLICATION_TYPE = APPLICATION_TYPE

3.3.3. 路由设计

根据不同的域名获取路由配置,根据路由配置生成路由;系统A和系统B各自维护一个路由列表;当从后端请求回来路由结构之后,根据不同的应用映射不同的文件内容;其中路由path保持不变,compoent增加前缀(应用类别)找到对应的应用下的组件;

•第一步:前端获取当前域名,确认当前应用

根据全局的 APPLICATION_TYPE 字段识别

•第二步:前端维护一个路由列表

let router=[
{
    path: '/home',
    component: Layout,
    meta: {  title: '首页', icon: 'el-icon-s-grid', alwaysShow: true },
    redirect: '/home',
    children: [
      {
        path: '/home',
        component: () => import('@/views/home/index'),
        name: 'home',
        meta: { title: '首页', icon: ''}
      }
    ]
  }
]

•第三步:根据当前应用请求后端接口,获取路由配置信息(component的路径前拼接各个应用的文件名)

let RouterApi={'a':'/api1','b':'/api2','c':'api3'}
api.get(RouterApi[APPLICATION_TYPE])
component='各个应用文件名'+接口返回路径

•第四步:针对在路由信息放置在前端的应用,前端维护一个路由的配置信息表

import dRouter from './d.json'
if(APPLICATION_TYPE==='d'){
   router=dRouter
}

•第五步:根据路由配置信息,生成路由结构

•第六步:实例化Vue对象

3.3.4. 环境变量设计

环境主要分为以下几种:mock环境、本地开发环境、测试环境、线上环境

不同的环境对应不同的变量文件,在变量文件中设置每个端需要用到的参数,结合 APPLICATION_TYPE 和变量文件的配置,获取到对应的参数

示例:

# .env.pruduction

# a 业务
VUE_APP_A_BASEURL = ''   
# b 业务
VUE_APP_B_BASEURL = ''
# c 业务
VUE_APP_C_BASEURL = ''
# d业务
VUE_APP_D_BASEURL = ''

3.3.5. 请求设计

1.公共请求的封装

封装基础的公共请求createHttp.js,各业务基于公共的请求和各自的code码,请求参数等信息进行再次封装,然后可以按照业务需求调用;

•基础请求:createHttp.js

•业务公共封装:

a. ARequest.js(A业务公共参数和code码处理)

b. BRequest.js (B业务公共参数和code码处理)

c. CRequest.js(C业务公共参数和code码处理)

d. DRequest.js(D业务公共参数和code码处理)

•业务层调用:

a. api/apiA A业务接口

b. api/apiB B业务接口

c. api/apiC C业务接口

// 公共请求封装  baseHttp.js
export const createHttp = (baseUrl, successFun = () => {}, errorFun = () => {}, requestInterceptor = () => {}) => {
  const http = axios.create({
    baseURL: baseUrl,
    timeout: 5 * 60 * 1000,
    withCredentials: true
  })
  // http request 拦截器
  http.interceptors.request.use(
    async config => {
      await requestInterceptor(config)
      return config
    },
    err => {
      return Promise.reject(err)
    }
  )
  // http response 拦截器
  http.interceptors.response.use(successFun, errorFun)
  return http
}
  1. 直接调用后端服务请求封装
//A业务基础请求 
function requestInterceptor(){
    // A系统公共请求参数处理... 
}
function successFn(){
    // A系统公共响应结果处理 统一新增
}
function errorFn(){
    // A共异常处理 包括code码等情况
}
export default createHttp(baseUrl,successFn,errorFn,requestinterceptor)
  1. 业务接口使用,根据不同的业务划分不同的目录分支
// A业务请求调用
ARequest.get(url,{params:data})
//B业务请求调用
BRequest.post(url,{params:data})

3.3.6. 权限和登录

根据应用类型字段APPLICATION_TYPE,识别不同的环境,请求不同的服务端接口;不同的服务端代表了不同的应用;

针对不同的应用的未登录情况,前端维护多套登录处理逻辑,根据应用类型进行不同的处理逻辑;

3.3.7. 公共函数设计

创建一个公共的utils文件夹,针对两个项目中的公共函数进行合并,针对有冲突的函数,进行命名修改,全局引入的部分进行路径和函数的同步修改;

3.3.8. 脚手架配置设计

梳理了两个项目的脚手架配置差异项及各个配置的作用,对配置作了部分的修改和优化,在满足原有的功能情况下不影响正常的项目运行;

3.3.9. Vuex store设计

store的整体结构保持不变,在项目引用的地址也保持不变,由于项目中使用store的地方较多,保持结构不变能保证改动成本最小,针对两个项目中模块名重复的情况,手动把模块里的内容进行合并;



大型前端应用如何做系统融合?



针对现有的名称重复内容不一样的函数,根据应用类型字段 APPLICATION_TYPE 把两个函数进行融合进行分别处理;

3.3.10. 页面引用设计

•引用方式变更

由于业务需求,应用A中嵌套了应用B的页面,之前通过iframe引用。融合后,页面文件和组件不再隔离,可以直接引入应用B的文件和组件;

•后端数据打通

应用A的后端服务器上有一些功能,如下载列表,应用B项目需要使用时因数据不通难以直接引用。前端融合后,可以在应用B中直接引用应用A的页面组件,实现业务的顺畅使用。效果如下:



大型前端应用如何做系统融合?



4. 总结

在经历了为期两个月的紧张工作后,我们成功地将两个大型项目进行了深度整合,取得了显著的阶段性成果。通过这一融合过程,我们不仅统一了项目的代码规范和架构,还显著提升了组件的复用率。尽管在这个过程中我们遇到了诸多挑战和曲折,但最终的成果——用户体验的显著提升——使一切努力都显得弥足珍贵。

我们深知,每一个成功的项目背后都有无数次的尝试和优化。在这个过程中,我们不断学习、适应和完善,最终实现了项目的无缝融合。我们相信,这段经历和我们所取得的成果,不仅为我们团队带来了宝贵的经验和教训,也可能为那些正在经历类似挑战的同学提供了一些启示和帮助。

作者:京东零售 高雅薇

来源:京东云开发者社区

点赞
收藏
评论区
推荐文章
互动玩法任务平台介绍
任务平台是科技内各业务方开展互动玩法的中心化平台,支撑科技内拉新、促活、交易等业务场景,包含基础任务、基于任务的通用活动玩法和业务投放能力。提供了任务玩法的创建、投放、曝光、完成等全生命周期的精细化管理,打造了基于任务的裂变、时间轴等通用活动玩法的规则化运营,致力于提升在多场景、多玩法、多频次的业务投放能力。任务中心主要战场是金融APP,目前日均500W的完成量,月UV100W,大促期间日完成量达2000W。
Stella981 Stella981
3年前
KubeSphere 正式入驻 AWS Quick Start,服务全球用户云原生落地
日前,面向云原生应用的容器平台KubeSphere宣布正式入驻AmazonWebServices(AWS)QuickStart,基于AmazonElasticKubernetesService(AmazonEKS)深度集成,为全球用户提供多集群管理、微服务治理、应用管理等功能,以极简的部署与管理,帮助企业快速落地
Stella981 Stella981
3年前
DBus数据库表结构变更处理方案
导读:DBus是我们要介绍的在敏捷大数据(AgileBigData)背景下的第一个平台。企业中大量业务数据保存在各个业务系统数据库中,为同时解决数据同步的一致性和实时性问题,DBus(数据总线)平台应运而生。DBus专注于数据的实时采集和实时分发,是一种基于日志的解决方案,同时能够提供消息订阅的方式给下游系统使用。本篇文章主要介绍在DBus的设计中,它
京东云开发者 京东云开发者
7个月前
【京东云新品发布月刊】2024年3月产品动态
1.【言犀模型服务】新品上线言犀模型服务平台致力于为开发者提供AI原生应用开发的全链路服务,内置丰富的应用插件,提供便捷的集成方式,结合企业专属数据和API,助力企业高效完成大模型应用构建。2.【数据库管理服务DMS】新品上线数据库管理服务DMS(Data
京东云开发者 京东云开发者
7个月前
技术分享-日志链路追踪
1.背景简述在技术运维过程中,很难从某服务庞杂的日志中,单独找寻出某次API调用的全部日志。为提高排查问题的效率,在多个系统及应用内根据统一的TraceId查找同一次请求链路上的日志,根据日志快速定位问题,同时需对业务代码无侵入,特别是在高频请求下,也可以
京东云开发者 京东云开发者
6个月前
【微电平台】-高并发实战经验-奇葩问题解决及流程优化之旅
微电平台微电平台是集电销、企业微信等于一体的综合智能SCRMSAAS化系统,涵盖多渠道管理、全客户生命周期管理、私域营销运营等主要功能,承接了京东各业务线服务,专注于为业务提供职场外包式的一站式客户管理及一体化私域运营服务。导读本文介绍电销系统【客户名单离
京东云开发者 京东云开发者
3个月前
从C端到B端:我的前端技术进阶之路
个人经历大家好,我叫付小波,2017年加入京东,现担任全渠道生态部前端架构师。我负责过ToC和ToB多个业务,近几年主要专注于B端应用开发。以下是我的主要经历:2017年:负责主站虚拟交易业务研发,搭建首个虚拟交易类小程序;2019年:从C端转向B端系统,
京东云开发者 京东云开发者
2个月前
“京东云深海数据平台” 焕新升级 免费体验!
深海数据平台致力于为每一个数据客户提供灵活化、一站式、智能化的数据开发与管理工具。同时,根据客户行业提供成熟的数据业务全链路解决方案,包括数据集成、开发、元数据管理等功能,帮助数据开发人员快速高效地完成数据相关工作,使得企业更加科学规划和合理构建全域数据,
京东云开发者 京东云开发者
10个月前
码上加速,低代码解锁高效交付案例
一、背景简介站长工作台,致力于为京东物流所有站长、运营管理人员提供高效工作平台,拥有多元化的业务形态。我们力求提升团队研发效率、实现敏捷业务交付,以打造一支具备灵活性、高度协作和强适应能力的敏捷团队。二、提效案例描述2.1、痛点分析站长工作台的报表页面和任
京东云开发者 京东云开发者
9个月前
到店商详架构变迁
一、项目背景到店商详是平台为京东到店业务提供的专属商详页面,将传统电商购物路径打造成以LBS门店属性的本地生活服务交易链路。二、架构变迁1、主站商详扩展点优点:到店侧仅关注业务,无需过度关注服务部署、性能优化等。缺点:涉及方较多,需求开发周期长,上线依赖