乐趣区

关于javascript:Vue-项目一套代码两个项目拆分方案

背景

因为之前的数据库防火墙产品与数据库审计产品应用的是同一套代码,随着两个产品性能的差别越来越大,代码的冗余度和偶合度越来越高,为了便于前期保护以及增加新性能,所以基于原来的我的项目代码,进行了代码构造拆分。

留神:本次拆分只拆分了能够拆分的局部,有的模块例如:规定、对于咱们,是没有进行拆分的,一是有的模块很简略,没必要拆分;二是有的模块原先写得代码偶合太重大,无奈拆分,如果要拆分,须要破费大量精力去梳理代码,同时还要后端配合拆分。

目标

将此次代码拆分计划记录下来,便于起初的开发人员疾速相熟我的项目构造。

拆分前

流程设计

我的项目拆分前,区分数审和防火墙性能的流程如上图所示。

拜访零碎时,先加载入口文件 main.js,而后加载登录页 login.vue,加载登录页的同时获取产品模式并保留到 session.storage.platformType 中,接着用户登录零碎进入具体页面,该页面同时蕴含了数审和防火墙的性能,依据 session.storage.platformType 保留的值来判断,具体显示哪个性能。

目录结构设计

我的项目拆分前的目录构造如上图所示。

该目录构造是初始化一个 Vue 我的项目时的根本目录,依据目录构造,基本上看不出该我的项目蕴含了两个不同的产品,也不晓得不同产品模式下会加载哪一部分文件,构造不清晰。

存在的问题

通过剖析,能够发现以后的零碎流程和目录构造是存在很多问题的,大略总结下:

  1. 加载登录页的时候才获取产品模式,如果登录页加载实现,而产品模式还未获取或者获取不到,那么登录页显示的产品信息有可能是谬误的;
  2. 每次进入一个具体页面,如果同时蕴含了数审和防火墙的性能,都要从新判断一次,以后的性能是数审的还是防火墙的;
  3. 目录构造不清晰,不分明哪些模块是公共模块,哪些是数审独有的模块,哪些是防火墙独有的模块;
  4. 可维护性和可扩展性差。数审的代码和防火墙的代码混在一个文件内,改代码的时候须要重头看一遍才晓得哪块代码属于数审,哪块代码属于防火墙。如果想要增加一个性能,还得持续加逻辑判断,代码越来越臃肿;
  5. 业务逻辑凌乱,与后端通信应用了同一个接口。

拆分后

流程设计

我的项目拆分后,区分数审和防火墙性能的流程如上图所示。

拜访零碎时,先加载入口文件 main.js,该文件中写了路由拦挡相干的逻辑,在路由拦挡时,如果没有产品模式,则要先获取产品模式,否则会被拦挡,进不去零碎。获取产品模式后,依据以后产品模式,会注册对应的登录页、路由配置、接口申请等。当注册结束后,每次拜访具体的页面,都应该是独立的模块了。

目录结构设计


我的项目拆分后的目录构造如上两个图所示。

该目录构造通过拆分,曾经能够清晰地看到不同产品之间分离出来的文件了,从入口文件开始,通过路由拦挡后,会加载指定的登录页,而后把对应产品须要的文件合并到公共文件中。比方:http 申请、路由配置等。最终后果,程序只会把须要的文件加载进去。

解决的问题

通过从新设计,解决了以后我的项目存在的一些问题:

  1. 在加载登录页之前,通过路由拦挡,必须先获取产品模式,能力进入零碎,登录页是在获取到产品模式之后才加载的,不会呈现产品信息显示谬误的问题;
  2. 只有在第一次进入零碎或刷新页面的时候,才会从新获取产品模式,合并产品模式对应的文件,合并的文件是拆分后的文件,不须要在文件内再次判断该无数审的性能还是防火墙的性能。
  3. 目录构造清晰,防火墙相干的功能模块文件都放在 views-fw 文件夹内。
  4. 进步了我的项目的可维护性和可扩展性,升高了代码的偶合度。数审的代码和防火墙的代码根本曾经拆离开,如果想要增加一个防火墙的性能,只须要在防火墙相干的文件夹内新增对应功能模块的文件即可。
  5. 业务逻辑清晰,与后端通信应用的是不同的接口,公共模块应用的接口按原来的不变,数审独有的接口在 url 后面减少了 audit 前缀,防火墙独有的接口在 url 后面减少了 firewall 前缀。

要害代码

/**
 * @Name: main.js
 * @Author: cqfeng
 * @Description: 我的项目入口 js 文件
 * @MainFunction: 引入和注册一些全局资源
 **/
//... 省略的代码...
// 路由拦挡,应用全局导航守卫 beforeEach
router.beforeEach(async (to, from, next) => {
    // 如果没有产品模式,先获取产品模式
    if (!store.state.productMode.productMode) {await store.dispatch('productMode/SET_PRODUCT_MODE');
    }
//... 省略的代码...
/**
 * @Name: product-mode.js
 * @Author: cqfeng
 * @Description: 产品模式相干逻辑解决文件
 * @MainFunction: 保留以后产品模式,依据不同产品模式配置 产品登录页、http 申请 等资源
 **/
import Vue from 'vue';
import portService from '@/assets/js/service/http/http'; // axios 申请
import router from '@/router/index'; // 默认路由配置,动静路由配置
import httpAAS from '@/assets/js/service/http/http-aas'; // 数审独有的 http 申请
import httpFW from '@/assets/js/service/http/http-fw'; // 防火墙独有的 http 申请
import globalConstant from '@/assets/js/const/global-constant'; // 我的项目全局常量
export default {
    namespaced: true,
    state: {productMode: '', // 产品模式,进入零碎或刷新页面时获取},
    mutations: {
        // 批改产品模式
        changeProductMode: function (state, value) {state.productMode = value;},
    },
    actions: {async SET_PRODUCT_MODE({ commit, state}) {let res = await portService.getProductMode();
            if (res.data.code === 0) {commit('changeProductMode', res.data.data.productMode);
            }
            // 如果是数审产品
            if (state.productMode === globalConstant.COMMON.AAS) {
                // 设置产品登录页
                router.addRoutes([
                    {
                        path: '/login',
                        name: 'login',
                        component: resolve => {require(['@/views/login.vue'], resolve);
                        },
                    }
                ]);

                // 合并 http 申请,挂载到 Vue 原型上
                Vue.prototype.portService = Object.assign(portService, httpAAS);
            }
            // 如果是防火墙产品
            else if (state.productMode === globalConstant.COMMON.DBSG) {
                // 设置产品登录页
                router.addRoutes([
                    {
                        path: '/login',
                        name: 'login',
                        component: resolve => {require(['@/views/views-fw/login.vue'], resolve);
                        },
                    }
                ]);

                // 合并 http 申请,挂载到 Vue 原型上
                Vue.prototype.portService = Object.assign(portService, httpFW);
            }
        }
    }
};

总结

通过拆分,数审和防火墙的代码目录曾经算是根本离开了,这个过程破费的力量也很大,也引发了我的一些思考,一套代码多个我的项目的这种计划是否算好的计划,还有没有其余更好的计划。如果我的项目一开始,就依照一套代码多个我的项目的设计来开发,会不会前期的保护老本会低一些?这些问题我也没有答案,心愿后来者可能继承历史教训,更好地开发出优良的我的项目。

其余实现形式

起初设计拆分计划的时候,有两种计划,一种是通过获取产品模式动静扭转以后产品性能,一种是在打包时通过打包参数打包指定产品包。最终的计划是抉择第一种。然而,在这个过程中也参考了一些网上的实现计划,这里列出来不便当前须要用到进行参考。

  1. 应用 vue 搭建多页面多零碎利用
  2. 基于 Vue-cli 的一套代码反对多个我的项目的解决方案
  3. vue 单页多页的开发环境配置 +vue 的开发思路
退出移动版