作者:京东批发 郑炳懿
开篇:
如果你不晓得微前端是什么,或者不晓得微前端能解决什么问题,那么你可能不须要微前端。
在我看来,对于每一个没有应用过的新技术,都应该有以下几个过程:
1、调研该技术,产出相应的调研文档。
2、输入技术 Demo,根本的框架结构。
3、试着在我的项目中应用它,这一步坑会很多。
4、把它推动到线上实现真正的技术升级。
一、调研微前端
1.1 业务背景
某次遇到一个从 0 到 1 的大型项目,该我的项目波及两个端,除了鉴权和局部业务逻辑不同外,页面 UI 和其余逻辑简直统一,遇到这种我的项目,该如何架构?既能保障我的项目顺利开发实现,又能保障前期的迭代、保护、可扩大?
1.2 初步计划
首先,想到的技术计划有这么两种:
1、复用同一套代码,通过判断不同的权限,服务端下发标识,解决异同的业务逻辑。
2、开发两套代码,两套鉴权各走各的,页面雷同局部从右边 Copy 到左边。
其次,回过头来想了想,这两种计划都有缺点:
1、复用同一套代码,前期迭代的过程中,业务差别越来越大的时候,就会造成“屎山”。
2、开发两套代码,前期迭代的过程中,如果业务仍然高度类似,那么每次都要把 A 我的项目中的代码 Copy 到 B 我的项目中;如果业务逐步有了各自的格调,那么两套代码的计划显然是更佳的。
最初,除此之外,还有别的更好的计划吗?
1.3 什么是微前端?
微前端的概念是由 ThoughtWorks 在 2016 年提出的,它是一种前端架构格调,将一个宏大的前端利用拆分成多个独立灵便的小型利用,每个利用都能够独立开发、独立运行、独立部署,再将这些小型利用交融为一个残缺的利用,或者将本来运行已久、没有关联的几个利用交融为一个利用。微前端既能够将多个我的项目交融为一,又能够缩小我的项目之间的耦合,进步开发效率和可维护性。微前端的外围在于解耦,通过拆分和集成来实现前端利用的可扩展性和灵活性。
图片来源于 micro-app 官网
二、初识微前端
2.1 微前端能力
1、独立开发:微前端能够将一个宏大的前端利用拆分成多个小型利用,每个利用都能够独立开发,不会影响其余利用的开发进度。
2、独立部署:每个小型利用都能够独立部署,不会影响其余利用的部署进度。这也意味着能够应用不同的技术栈、不同的部署形式、不同的版本控制工具等。
3、独立运行:每个小型利用都能够独立运行,不会影响其余利用的运行状态。这也意味着能够应用不同的框架、不同的库、不同的语言等。
4、集成灵便:微前端框架能够将多个小型利用集成为一个残缺的前端利用,或者将本来运行已久、没有关联的几个利用交融为一个利用。这也意味着能够依据须要动静地减少或删除利用。
5、解耦:微前端能够将前端利用拆分成多个小型利用,每个利用都有本人的职责和业务逻辑,能够缩小利用之间的耦合,进步可维护性和可扩展性。
6、增量降级:微前端能够实现增量降级,只须要降级须要更新的小型利用,而不须要降级整个前端利用。这能够缩小降级带来的危险和老本。
2.2 微前端外围
1、拆分:将前端利用拆分成多个小型利用,每个利用都有本人的职责和业务逻辑。这样能够缩小利用之间的耦合,使得每个利用都能够独立开发、独立部署和独立运行。
2、集成:通过微前端框架将多个小型利用集成为一个残缺的前端利用。这样能够依据须要动静地减少或删除利用,实现灵便的集成。
3、通信:通过定义接口和事件等形式,实现小型利用之间的通信。这样能够保障各个利用之间的合作和交互,同时又不会影响利用之间的耦合。
4、款式隔离:通过应用款式隔离技术,使得每个小型利用都能够应用本人的款式,不会影响其余利用的款式。这样能够保障各个利用之间的款式不会相互烦扰,同时又不会影响利用之间的耦合。
总之,微前端的外围是解耦,通过拆分、集成、通信和款式隔离等形式,实现前端利用的解耦,进步可维护性和可扩展性。
2.3 微前端平台
1、single-spa 是一个将多个单页面利用聚合为一个整体利用的 JavaScript 微前端框架。
2、qiankun 蚂蚁金服出品,基于 single-spa 封装的微前端框架。
3、MicroApp 京东出品,一款基于 WebComponent 的思维,轻量、高效、功能强大的微前端框架。
因为我的项目应用的 umi + react +ts 的技术栈,而 qiankun 天生就集成在 umi 框架中了,只须要一些配置就能够应用微前端技术,留神,我这里说的是一些配置,就是这一些配置,让我放弃了 qiankun 微前端框架,因为 single-spa 要求子利用批改渲染逻辑并暴露出三个办法:bootstrap、mount、unmount,别离对应初始化、渲染和卸载,这也导致子利用须要对入口文件进行批改。而 qiankun 是基于 single-spa 进行封装,所以这些特点也被 qiankun 继承下来,并且须要对 webpack 配置进行一些批改,老本绝对较高。
再来看 micro-app 老东家出品的微前端框架,借鉴了 WebComponent 的思维,通过 CustomElement 联合自定义的 ShadowDom,将微前端封装成一个类 WebComponent 组件,从而实现微前端的组件化渲染。并且因为自定义 ShadowDom 的隔离个性,micro-app 不须要像 single-spa 和 qiankun 一样要求子利用批改渲染逻辑并暴露出办法,也不须要批改 webpack 配置,是目前市面上接入微前端老本最低的计划。
图片来源于 micro-app 官网
三、利用微前端
3.1 抉择 mirco-app
联合上述的调研后果,决定应用 micro-app 框架来架构我的这个大型项目。第一,micro-app 应用简略,学习成本低,玲珑的体积和更高的扩展性;第二,老东家的技术,必须全力支持。
确定最终技术计划:
1、我的项目波及到两个端,筹备启用两个基座,这两个基座内治理鉴权和对立调用的公共逻辑,基座独立部署,属主利用。
2、我的项目中雷同的 UI 局部,独立到业务组件库,可复用,业务逻辑局部,各自在我的项目中解决,互相独立。
3.2 启动 mirco-app
这里有具体的应用文档,就不再赘述,从引入依赖到我的项目齐全渲染进去,只须要四步即可,micro-app 直通车。
值得一提的是第二步,有个小坑,入口处引入包,而后调用办法。
如果你的我的项目是 Vue 的话,这里说的入口文件应该是 main.js;如果你的我的项目是 umi 框架的话,入口文件指的的是 src/pages/.umi/umi.js 文件,这个文件是 umi 主动生成的,无奈让你在这外面编码,所以你须要在 src 目录上面新建一个 index 或者 global 的文件,把上面的代码复制进去。
// 我的项目入口处引入
import microApp from '@micro-zoe/micro-app'
microApp.start()
依照文档的指引,你应该看到这个界面,如果没有看到这个界面,那阐明你的姿态有问题,可能是跨域导致,对于逾越问题,Q&A 外面有解决方案,用《程序员的修炼之路》中的一句话来说:“读一下那些该死的报错信息”,没准你就能启动胜利了。
顶部导航和左侧菜单是基座,也就是主利用,右侧的内容区域,是子利用。
3.3 踩坑 micro-app
3.3.1 路由问题
我的项目启动起来要面对的第一个问题就是路由问题。案例外面给的菜单是一级菜单,然而理论我的项目利用中可能有二级、甚至三级菜单,那怎么匹配路由跳转到对应的子利用呢?
外围代码:
microApp.router.push({
name: 'pop', // 子利用名称
path: `${config.pop}${item.url}` // config 是配置文件 item 是以后点击的菜单门路信息
});
解决逻辑:
1、优先解决树形菜单,树形菜单应用递归调用,前期不论是几级菜单都不必管它了。
2、与服务端约定好树形菜单的字段,出必要字段外,应该蕴含对应的子利用名称,门路,icon 图标等信息,这些信息是你提前给服务端,配置到表构造中的。如果我的项目足够大的话,能够启一个 SaaS 零碎,更加灵便和牢靠。
3、当点击菜单中对应的某个菜单时,取到以后门路拼接域名即可实现跳转。
<micro-app
name="pop"
url={config?.pop}
/>
3.3.2 面包屑问题
强烈建议把面包屑放到子利用中,面包屑在子利用中的益处是自在实现跳转,不必主利用做特地的解决,惟一须要解决的是面包屑外面的首页,因为面包屑放到子利用中,点击回首页时,回到的其实是子利用的首页,并非是主利用的首页。
主利用解决逻辑:
import React from 'react';
import config from '@/config';
/** @jsxRuntime classic */
/** @jsx jsxCustomEvent */
import jsxCustomEvent from '@micro-zoe/micro-app/polyfill/jsx-custom-event';
export default ():React.ReactElement => {
// 子利用点击了面包屑的回到首页
const onDispathChild = (e:any) => {const { isBackHome} = e.detail.data;
if (isBackHome) window.location.href = '/';
};
return (
<>
<micro-app
name="pop"
url={config?.pop}
default-page={`${config?.pop}${config.defaultUrl}`}
onDataChange={onDispathChild}
/>
</>
);
};
子应用逻辑:
// 点击回到首页的时候, 须要通知父利用, 让父利用去重置路由
const onBackHome = () => {window.microApp?.dispatch({ isBackHome: true});
};
micro-app 在 window 上面挂载了一个全局的对象,咱们只须要去触发它提供的办法,实现奴才之间的通信即可,这个逻辑想明确之后,不论是交互逻辑还是数据传递逻辑,一通都通。
3.3.3 打包问题
奴才利用两个我的项目,在进行打包的过程,做了分包的解决,micro-app 中的 js 沙箱隔离技术有点小缺点,因为奴才利用应用的都是 umi 的框架,打包之后会谬误的把子利用的包插入主利用中,导致利用报错,加载不进去。
解决逻辑:
// 不宰割组件
dynamicImport: false,
因为在理论我的项目操作中遇到的问题可能会比以上列举的比拟多,下面举了几个典型的例子,后续大家如果应用中遇到什么问题,也能够私信我进行解决,或者留言评论。
四、总结微前端
最终咱们的这个大型项目采纳微前端实现了业务解耦,维护性高,扩展性高的冀望,前期迭代 so easy。
用起来其实还是蛮简略的,然而用好了不容易,目前咱们正在布局把一整个业务线集成到微前端中,因为有些我的项目太老了,无奈保护了,把这些老我的项目间接一个链接成子利用,新的迭代的都独立成一个独自的子利用,能够应用新框架,新技术去实现,技能进步开发效率,又能很好的扩大和迭代,集体感觉微前端技术很优良,很受用。
以下是一些拆分逻辑,心愿给应用微前端技术的同学一些参考:
应用微前端拆分一个大型项目须要留神以下几点:
1、拆分粒度:应该依据业务性能、团队职责、技术栈等因素来确定拆分粒度。拆分粒度太小会减少利用之间的通信老本,拆分粒度太大会影响独立开发和部署的能力。
2、拆分边界:应该确定每个小型利用的边界,使得每个利用都有本人的职责和业务逻辑。拆分边界应该尽可能地缩小利用之间的耦合,同时又保障各个利用之间的合作和交互。
3、通信形式:应该确定小型利用之间的通信形式,包含接口、事件等。通信形式应该尽可能地简略和高效,同时又可能满足各个利用之间的合作和交互需要。
4、数据管理:应该确定小型利用之间的数据管理形式,包含数据共享、数据隔离等。数据管理形式应该尽可能地简略和高效,同时又可能满足各个利用之间的数据共享和隔离需要。
5、款式隔离:应该应用款式隔离技术,使得每个小型利用都能够应用本人的款式,不会影响其余利用的款式。这样能够保障各个利用之间的款式不会相互烦扰,同时又不会影响利用之间的耦合。
6、集成形式:应该确定集成形式,包含微前端框架的抉择、部署形式等。集成形式应该尽可能地简略和高效,同时又可能满足各个利用之间的集成需要。
总之,应用微前端拆分一个大型项目须要留神拆分粒度、拆分边界、通信形式、数据管理、款式隔离和集成形式等方面,以实现前端利用的解耦,进步可维护性和可扩展性。