-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
带你手写微前端框架 #4
Labels
documentation
Improvements or additions to documentation
Comments
👍 |
bang |
学习single-spa思想 |
awesome |
🆒 |
大佬继续完善 |
通讯问题如何解决,有没有思路和完整demo奉上。。。多谢张老师 |
serve插件中的port是number类型 |
学习了 感谢大佬的分享 |
不明觉厉 |
大佬 厉害 有没有另一种是纯功能(Feature)级别的,称之为service的微前端demo或git地址 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
关注核心实现请直接跳至 第四小节:执行流程。
一、初始化工程
1、初始化工程目录
2、初始化npm环境
import()
进行动态导入,当前在Stage 4: finished
的阶段3、配置babel和rollup
# 创建babel.config.js touch babel.config.js
然后添加内容:
# 创建rollup.config.js touch rollup.config.js
然后添加以下内容:
4、在package.json中添加script和browserslist字段
4、添加项目文件夹
到目前为止,整个项目的文件夹结构应该是:
到此,项目就已经初始化完毕了,接下来开始核心的内容,微前端框架的编写。
二、app相关概念
1、app要求
微前端的核心为app,微前端的场景主要是:将应用拆分为多个app加载,或将多个不同的应用当成app组合在一起加载。
为了更好的约束app和行为,要求每个app必须向外export完整的生命周期函数,使微前端框架可以更好地跟踪和控制它们。
2、app状态
为了更好的管理app,特地给app增加了状态,每个app共存在11个状态,其中每个状态的流转图如下:
状态说明(app和service在下表统称为app):
bootstrap
生命周期函数)bootstrap
生命周期函数中(只执行一次)bootstrap
或unmount
生命周期函数执行成功,等待执行mount
生命周期函数(可多次执行)mount
生命周期函数中mount
或update(service独有)
生命周期函数执行成功,意味着此app已挂载成功,可执行Vue的$mount()或ReactDOM的render()unmount
生命周期函数执行中,意味着此app正在卸载中,可执行Vue的$destory()或ReactDOM的unmountComponentAtNode()只有service才会有此状态,app则没有
SKIP_BECAUSE_BROKEN
,那么app就会blocking
,不会往下个状态变更load、mount、unmount条件
判断需要被加载(load)的App:
判断需要被挂载(mount)的App:
判断需要被卸载(unmount)的App:
3、app生命周期函数和超时的处理
app的生命周期函数何以传入数组或函数,但是它们都必须返回一个Promise,为了方便处理,所以我们会判断:如果传入的不是Array,就会用数组将传入的函数包裹起来。
具体的流程如下图所示:
为了app的可用性,我们还讲给每个app的生命周期函数增加超时的处理。
三、路由拦截
微前端中app分为两种:一种是根据Location进行变化的,称之为app。另一种是纯功能(Feature)级别的,称之为service。
如果要实现随Location的变化动态进行mount和unmount那些符合条件的app,我们就需要对浏览器的Location相关操作做统一的拦截。另外,为了在使用Vue、React等视图框架时降低冲突,我们需要保证微前端必须是第一个处理Location的相关事件,然后才是Vue或React等框架的Router处理。
四、执行流程(核心)
整个微前端框架的执行顺序和js事件循环相似,大体执行流程如下:
触发时机
整个系统的触发时机分为两类:
registerApplication()
或start()
方法。修改队列(changesQueue)
每通过触发时机进行一次触发操作,都会被存放到changesQueue队列中,它就像事件循环的事件队列一样,静静地等待被处理。如果changesQueue为空,则停止循环直至下一次触发时机到来。
"事件"循环
在每一次循环的开始阶段,会先判断整个微前端的框架是否已经启动。
未启动:
根据规则(见上文的『判断需要被加载(load)的App』)加载需要被加载的app,加载完成之后调用内部的finish方法。
已启动:
根据规则获取当前因为不满足条件而需要被卸载(unmount)的app、需要被加载(load)的app以及需要被挂载(mount)的app,将load和mount的app先合并在一起进行去重,等unmout完成之后再统一进行mount。然后再等到mount执行完成之后就会调用内部的finish方法。
通过上文我们可以发现不管是当前的微前端框架的状态是
未启动
或已启动
,最终都会调用内部的finish方法。其实,finish方法的内部很简单,判断当前的changesQueue
是否为空,如果不为空则重新启动下一次循环,如果为空则终止终止循环,退出整个流程。location事件
另外在每次循环终止时都会将已拦截的location事件进行触发,这样就可以保证上文说的微前端框架的location触发时机总是首先被执行,而Vue或React的Router总是在后面执行。
最后
微前端框架仓库地址:https://github.com/YataoZhang/my-single-spa
The text was updated successfully, but these errors were encountered: