根据微前端原理解决代码冲突--居然还有额外好处

本篇文章参考以下博文

前言

  我们开发的过程中,如何能提高开发效率?这是一个合格程序员始终都要考虑的问题,在前段时间的开发过程中,发现同事们在代码提交的时候,总会或多或少的有一些代码冲突,由于公司是使用的 SVN 进行代码管理的,要迁移到 Git 的话成本太高,所以就思考,有没有什么方法能够避免掉这个冲突,修改又不用很大?

  结合以前的项目,配置路由的时候,把所有页面的入口引入到一个配置文件中,路由在匹配入口的时候,也从配置文件中读取,这样解耦各个页面之间的功能。

  借鉴这个思路,组件之间应该也可以实现类似这种模式。

页面样例

  举个例子,我们需要实现下面这样一个页面。
在这里插入图片描述

  由于页面功能比较复杂,整个页面被划分为四个模块 A, B, C, D ,分别交给四个开发来完成,理想很美好,大家各自开发各自的模块,互不影响,但是当 A, B 页面都需要修改父组件的某些功能的时候,就很容易出现代码冲突。

  按照上面的配置文件的思路,我们这样来配置 config 文件。

import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
import ComponentC from './ComponentC';
import ComponentD from './ComponentD';

export BaseInformation = {
	A: {
		href: '#html_A',
		title: 'title_A',
		className: 'class_A',
		component: ComponentA,
	},
	componentList: [
		{
			href: '#html_B',
			title: 'title_B',
			className: 'class_B',
			component: ComponentB,
		},
		{
			href: '#html_C',
			title: 'title_C',
			className: 'class_C',
			component: ComponentC,
		},
		{
			href: '#html_D',
			title: 'title_D',
			className: 'class_D',
			component: ComponentD,
		}
	]
}

  上面代码中,我们可以看到,当各个开发人员完成组建后,引入到这个配置文件即可。

  解释下上面的思路:

  • href :为组件的路径,为了方便锚点定位识别
  • title :组件标题
  • calssName :组件唯一类名
  • component :组件

  这里解释下为什么 BaseInformation 里面要分成 A componentList 两个属性,而不是 A,B,C,D 四个。主要是页面组成导致我们配置需要灵活变化,样例的页面可以分为左右结构,左边是 A 组件,右边三个按顺序排列的组件,为了遍历方便,我们可以把右侧的三个组件直接放到数组中,遍历数组完成组件渲染。

  下面是父组件引入的时候,正对配置文件的一些编码:

import { BaseInformation } from './config'

function Father(props) {
	return (
		{/* 左侧 A 组件 */}
		{
			<BaseInformation.A.component />
		}
		{/* 右侧 B,C,D 列表 */}
		<div>
			{
				BaseInformation.componentList.map(item => {
					return (
						<item.component id={item.gref} className={item.ClassName} key={item.id} />
					)
				})
			}
		</div>
	)
}

代理目的

  这样我们就完成了,父对子的一层代理,这个时候有的同学可能会疑问,为什么要增加这一次层代理,直接引入不香嘛?

  我们直接引入第一,不方便查找,通过这种代理引入,我们可以很清晰的查看到每个组件的位置。我们平时在开发过程中,总需要消耗一段时间去熟悉项目中组件间的关系,尤其是接手别人的项目的时候,这种方式可以让我们快速理清组件间的相互关系。

  第二,可以解决一部分样式泄漏问题,代理的配置文件是由一个人进行配置的,那么可以保证类名不重复。

  第三,大家开发完组件后,只需要引入到这个 config 文件中即可,每个组件都是独立的,这样会大大降低代码冲突的问题,从而提高开发效率。各个模块的开发人员不需要了解模块是怎么被引入到页面的,不需要修改父组件。

  由于使用的配置文件的形式,组件间的耦合降低了,那为了确保通信,我们需要使用一个状态管理容器,比如 Redux

  当然了上面的引入方法只是一个简易的实现,我们还可以通过对配置文件的层级进行划分,明确出组件间的树形关系。比如下面这种形式:

export BaseInformation = {
	father: {
		href: '#father',
		title: 'title_father',
		className: 'class_father',
		component: ComponentFa,
		chlidren: [
			{
				href: '#html_son',
				title: 'title_son',
				className: 'class_son',
				component: ComponenSon,
			},
		]
	},
}

  这种方式可以直观的查看到,组件的嵌套关系。

  当然了,配置文件如果这样写,只能由划分组件的人那个人进行设置,这样缺少些灵活性,我们可以借鉴 qiankun 微前端框架。使用形式类似下方这种模式。

import { loadMicroApp } from 'qiankun';

/** 手动加载一个微应用 */
const microApp = loadMicroApp(
  {
    name: "microApp",
    entry: "https://localhost:7001/micro-app.html",
    container: "#microApp"
  }
)

// 手动卸载
microApp.mountPromise.then(() => microApp.unmount());

  上面是 qiankun 的引入和使用方式,是不是我们配置文件的一些信息及其相似,我们可以把刚才的代理封装一下,让它可以灵活的手动添加和卸载相应的组件,那这样我们在控制某个组件的显示隐藏时,不需要再新增一个变量来控制它的显示与否了。在任何地方,只要你喜欢,就可以随意控制任何组件的挂载。

  具体实现的方式,请关注我的后续博客,里面会对封装方法,进行详细描述,或者各位同学可以参考 qiankun 的封装模式,大部分封装手段借用了其中的思想。




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值