乾坤-qiankun 微前端 从0-1开始使用

首先先描述下使用场景

公司业务逐渐的多了起来 对应业务的后台也就越来越多,有公司的ERP系统,有商家后台系统,有老版APP后台管理系统和新版APP管理系统,解释下这个新老APP后台管理。
老版本是混合式开发由后端同学维护,但是遇到复杂的交互场景及大量的前端校验时后端同学写起来很吃力,所以有了新版后台管理系统,逐渐的新需求会在新版来做,原有的后台功能由老版本维护,所以新老后台联动性十分强,运营人员往往需要来回跳转查看操作。为了解决这个问题打算用微前端的方案来把新老后台融合起来,并且最终的目标是把用微前端的概念形成一个平台把公司的其他后台系统都接进来。

大家千万不要有先入为主的观念,对iframe有偏见,现在好多的前端同学工作年限不是很长,入行的时候就已经是移动端蓬勃发展的时候甚至都没怎么和iframe打过几次交道认为这是一个很老并且比较少用的标签。其实iframe就是最早的微前端解决方案,并且也是十分好用、方便、成熟的解决方案。

有了计划后20年中旬就开始关注起来了这一块,看了网上的一些关于乾坤的文章。总体来说好长三点
1、分割巨石应用,系统越开发越大,无论是生成环境还是开发环境都会感觉到迟缓,把大应用拆成相互独立的小应用解决这个问题。
2、很重要的一条与技术栈无关,可以用混合式开发,可以vue、react、angular。
3、不用担心版本兼容问题,不用为了老版本迁就放弃了新技术,其实和第二点说的是一个。
4、新增了一种项目与项目之间的传递信息的方式。
但是我感觉这些事情iframe做不了吗?一样的呀!想嵌套什么嵌套什么,iframe不能通讯吗也可以的呀!
被大家诟病的地方是 当iframe中的子应用切换路由时用户刷新页面整个网页又回到了原点。或是iframe对于父作用域需要样式的支持等,那又能怎样呢 在我看来这些都不是十分严重的缺点。
经过后来的考量是选用了乾坤,最大的原因是向前看嘛,现在微前端的概念这么火,好不容易公司有这方面的需求,我怎么能放过这个磨炼自己的机会,说以上这些就是想告诉大家 iframe 也是很不错的不要对它有太大的偏见。

最近一段时间每次打开乾坤官方查阅的时候都发现有变化,好多我以前思考探索了好久的问题在官网上都新增标注出来,发版的频率也是快了许多,甚至最近连乾坤的logo都变了,足以看出这个框架倍受关注在快速的迭代,给我感觉是在D2前端技术论坛之后,在直播期间被多次提到微前端--乾坤,吸引了大家的目光,无所谓了只要是快速发展越成熟对我们这些搬砖人员越有利不是吗。

开始正式合并

先来给大家看下成品的展示样子,目标对象是vue项目与混合式开发的php项目融合。


乾坤-qiankun 微前端 从0-1开始使用_第1张图片
展示图.png

可以看到项目的结构是这样的 中间的大片区域是给子程相互切换展示的,左侧导航和头部是主程展示的,同时只渲染一个子程项目,主程控制路由的匹配切换,菜单栏的请求获取和用户的身份登录等

一、注册子应用信息
registerMicroApps 应用注册信息,这个项目有多少个子应用是从这里开始注册的 给各个子应用传递state参数。
思路是不要手写,写成可配置项,日后需要新增子项目时直接追加配置信息即可。


乾坤-qiankun 微前端 从0-1开始使用_第2张图片
image.png

乾坤-qiankun 微前端 从0-1开始使用_第3张图片
image.png

循环配置项生成registerMicroApps所需要的应用格式,
这其中需要注意的是entry 和 porps。
作为入口分为生产环境和开发环境,生产环境走域名,开发环境走端口,用process.env.NODE_ENV区分,顺便来提下process是node的全局变量 env是他的一个属性存储着环境信息NODE_ENV大家都用这个属性 甚至是webpack,讲道理你的项目中应该有两个这样的变量 一个是你们项目的环境配置变量,可以分为dev test release product 另一个是 process.env.NODE_ENV 这个是区分生产和开发production/development,你可以给NODE_ENV重新赋值但是一般没什么用,因为webpack的mode会改变回来。
props 项目开始注册是每个子应用信息传递进去的state都是相同的,运行过几轮以后state会改变,此时再切换你会发现被切换的子应用用的还是原来的state,所以这里是写成了一个函数的信息每次切换会调用这个函数,函数内部走的工厂模式都是返回最新的state信息。

二、开始时的调用 start

不要直接调用start函数 子应用和主程应用同时渲染可能会报错,原因是主程没有渲染完毕子程就介入进来找不到要插入的节点而报错。


乾坤-qiankun 微前端 从0-1开始使用_第4张图片
image.png

render渲染主程项目,用回调函数的形式把start传递进去,在主程的mounted的生命周期中执行回调,最好再加个nextTick。

三、主程与子程的通信

这两个的衔接点肯定是用 setGlobalState 但是 setGlobalState是送到vue的根节点位置,进入了vue后续通信就用vuex来实行。


乾坤-qiankun 微前端 从0-1开始使用_第5张图片
image.png

一进来就发起一个dispatch把所有的props 都加入到vuex中,
并且定义好如果接受到了外面的任何改变再次调用dispatch再次执行存储
把setGlobalState挂在vue的原型上 用加了&& 为什么加了两个后面说。


乾坤-qiankun 微前端 从0-1开始使用_第6张图片
image.png
项目内任何想要改变全集state的地方可以调用globalAction 函数 会自动改变自己的vuex值 并且调用$$_setGlobalState 通知主程。
同样的方法 如果react作为子程项目可以结合redux。

.

四、子程的接收

子程区分是否被乾坤包裹,被包裹和不被包裹是两种逻辑,
1、如果没被包裹要初始化 setGlobalState onGlobalStateChange 以及props 不能让vue实例报错,把任务分开 main.js 就是负责实例化一个vue,这些是否被包裹以及导出乾坤所需的生命周期再提升一个层级来做。
2、没被包裹是分情况的,生产环境不允许自己独立运行所以强制跳转,被包裹的情况要重新更改webpack_public_path 因为域名地址不一样,不重新覆盖vue找不到资源路径
3、可以判断如果没被包裹引入 @babel/polyfill

乾坤-qiankun 微前端 从0-1开始使用_第7张图片
image.png

4、被包裹与否 是影响到项目样式的,如果没被包裹要渲染自己的layout也就是导航部分和头部,被包裹反之不用,而且这也影响到路由部分
image.png

乾坤-qiankun 微前端 从0-1开始使用_第8张图片
image.png

之所以要这写是不想影响原有流程,第一 dev 和 test环境 原本怎么开发还是怎么开发既不用乾坤包裹也能运行,这样做开发编译速度更快,多一层包裹肯定影响页面速度,而且页面dom层级较深也不容易调试,并且不给测试同学带来困扰,因为他们已经熟悉了原本的测试界面样子。第二生产环境自动跳入乾坤包裹,会有判断当前环境是预发或是线上自动跳转过来,所以其余环境都不用管,正常开发 上线了以后会自动被乾坤包裹。这样不影响任何人开发同学正常开发,测试同学正常测试。

五、混合式后台的改动

这个可说的就不多了,jq使劲撸就行了,总结两点吧。
1、页面可能会出现部分的图片找不到 老样子也是用乾坤传递进来的变量一个个的赋值

.loading {background:url("+ window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ +"style/src/adminhtml/images/loading.gif) no-repeat center; height:100px}

2、生命周期的导出
找到根文件


image.png
最后总结下

文章已经太长了,代码截图的并不全,其实就是几个关键点的思路都指了出来,毕竟是公司的项目我也不能把代码都贴出来而且也很难看又臭有长的代码。
说几个坑点。
文章前面我为什么夸了一圈iframe 因为页面大了真的卡,主进程用vue写子进程也用vue写,一个浏览器运行两套vue会卡到你怀疑人生,乾坤会代理window在你切换走的时候找到在刚刚执行过程中这个子应用都往window挂载了哪些东西,然后把这些都被挂载的都移除掉并缓存起来等到你再次切换回来的时候乾坤再帮你还原,乾坤会把一整个vue保存起来速度慢的很,跑demo感觉不出来的,demo就是一个空vue,真正用起来后你才能知道,不是两个vue卡是乾坤处理清除保存vue卡,react也一样的。
我这边的解决办法是用一个vue,主程加载vue子程用主程的vue,这样乾坤也不会处理这个vue速度快很多。但是有一个不好就是vue会被污染,在子程挂在的组件主程上也有,这也是为什么v3出createApp 我一眼就能看出这个是干什么用的,如果没遇到我可能不会理解为什么要出这个函数原本的new 不香吗。

跨域问题,加载html的时候可能会出现跨域,要自己写fecth解决。

无法实现keepalive 最近已经有运营和客服和我反馈了,怎么有时页面切换了数据就没了,正在新建优惠券切换下刚刚填写的信息就没了,当然没了两套系统怎么能保留。
最近也在思考这个解决办法。
1、vue这边用sessionstorage在路由变动时把当前页面的信息保留下来,例如正在创建直播 或是优惠券这些需要填写的页面 信息存储,切换回来的时候再还原。
2、老后台html 因为这些逻辑不是我写的,所以不能贸然的深入业务中去更改代码。解决思路是不要销毁老后台的实例,创建了就创建了切换后我就把这一整块div隐藏掉然后正常加载vue这边的子应用,切换回来后 vue应用销毁,这边的老后台应用展示 使用loadMicroApp 唯一不好的地方是 全集样式会污染,老后台会影响新后台的样式。这个我计划切换时div保留但把老后台的样式注释掉,切换回来后我再取消注释,这是我的想法具体还要看怎么实施。

你可能感兴趣的:(乾坤-qiankun 微前端 从0-1开始使用)