美文网首页
single-spa框架分析

single-spa框架分析

作者: 我是小布丁 | 来源:发表于2021-09-05 22:00 被阅读0次

    single-spa的原理其实很简单,它就是一个子应用加载器 + 状态机的结合体,而且具体怎么加载子应用还是基座应用提供的;框架里面维护了各个子应用的状态,以及在适当的时候负责更改子应用的状态、执行相应的生命周期函数

    1、single-spa的状态

    注册、加载、初始化、挂载、卸载、移除、错误


    image.png

    LOAD_ERROR,这通常是由于下载应用程序的js包时出现网络错误造成的。Single-spa将在用户从当前路由导航并返回后重试加载应
    SKIP_BECAUSE_BROKEN,应用在加载、初始化、挂载或卸载过程中抛出错误,由于行为不当而被跳过,因此被隔离。其他应用将正常运行

    2、single-spa 源码分析

    源码的 rollup.config.js 中可以看出,入口文件为 /src/single-spa.js,这个文件导出很多方法和状态值

    registerApplication 注册子应用

    single-spa/src/applications/apps.js

    1. sanitizeArguments(appNameOrConfig, appOrLoadApp, activeWhen,customProps),格式化用户传递的应用配置参数
    2. getAppNames() ,去重判断
    3. apps.push(app),将新的应用最加到apps中,并添加一些内置属性status、loadErrorTime、parcels、devtools
    4. ensureJQuerySupport() jQuery打补丁
    5. reroute(),更改app.status和执行生命周期函数

    reroute 更改app.status和执行生命周期函数

    single-spa/src/navigation/reroute.js

    1. 将apps分为4类,需要被移除的、需要被卸载的、需要被加载的、需要被挂载的
    2. 已经start(),将4类合在一起,执行performAppChanges()
    3. 没有start(),执行loadApps(),把需要被加载的执行toLoadPromise

    performAppChanges()

    1. dispatch事件
    2. 取消导航,执行finishUpAndReturn(),并且导航到旧的地址上
    3. 没有取消导航,
      需要被移除的,直接执行toUnloadPromise;
      需要被卸载的,先执行toUnmountPromise,再执行toUnloadPromise;
      需要被加载的,先执行toLoadPromise,执行toBootstrapPromise,等到移除和卸载完成再执行toMountPromise
      需要被挂载的,先执行toBootstrapPromise,等到移除和卸载完成后再执行toMountPromise
      最后把移除和卸载的完成后,把loadThenMountPromises + mountPromises合一起,完成后执行finishUpAndReturn()

    toLoadPromise(app)

    1. 如果已经存在app.loadPromise,说明已经被加载过,直接返回
    2. 只有状态为NOT_LOADED和LOAD_ERROR的app才可以被加载,其他状态直接返回
    3. 设置app.status = LOADING_SOURCE_CODE;
    4. 执行app.loadApp(props),返回一个promise。这个promise.then得到用户定义的生命周期方法:bootstrap、mount、unmount、unload、timeouts
    5. 设置app.status = NOT_BOOTSTRAPPED;
    6. 把得到的生命周期方法挂到app中,然后删除app.loadPromise

    toBootstrapPromise(appOrParcel, hardFail)

    1. 只有NOT_BOOTSTRAPPED状态可以被初始化,其他状态直接返回
    2. 设置appOrParcel.status = BOOTSTRAPPING
    3. 执行生命周期方法bootstrap
    4. 设置appOrParcel.status = NOT_MOUNTED

    toMountPromise(appOrParcel, hardFail)

    1. 只有NOT_MOUNTED状态可以被挂载,其他状态直接返回
    2. 执行生命周期方法mount
    3. 设置appOrParcel.status = MOUNTED

    toUnmountPromise(appOrParcel, hardFail)

    1. 只有MOUNTED状态可以被卸载
    2. 设置appOrParcel.status = UNMOUNTING
    3. 执行生命周期函数unmount
    4. appOrParcel.status = NOT_MOUNTED

    toUnloadPromise(app)

    1. 维护自己的移除队列appsToUnload
    2. NOT_LOADED状态,直接执行finishUnloadingApp(app, unloadInfo),清除工作,设置app.status = NOT_LOADED
    3. UNLOADING状态,等待移除完成
    4. 非NOT_MOUNTED和非LOAD_ERROR,需要等到挂载完成,再进行移除
    5. 执行生命周期函数unload
    6. 设置app.status = UNLOADING
    7. 移除完成,执行finishUnloadingApp(app, unloadInfo),完成清除工作,设置app.status = NOT_LOADED

    start(opts)

    调用start之前,应用会被注册和加载,但不会被初始化、挂载、卸载

    路由监听

    • hashchange:当URL中的片段标识发生改变时,会触发此事件
    • popstate:当活动历史条目更改时,触发popstate事件。需要注意的是调用history.pushState()或history.replaceState()不会触发popstate事件。只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在JS代码中调用history.back()或者history.forward()方法)
    window.addEventListener("hashchange", funcRef, false);
    window.addEventListener("popstate", funcRef, false);
    
    • history.pushState(state, title, url) 向当前浏览器会话的历史堆栈中添加一个状态
    • history.replaceState(state, title, url) 修改当前历史记录实体
    history.pushState({foo: "bar"}, "", "bar.html");
    history.replaceState({foo: "bar"}, "", "bar2.html");
    

    3、single-spa的缺点

    single-spa 就做了两件事,加载微应用(加载方法还是用户自己提供的)、维护微应用状态(初始化、挂载、卸载)。
    single-spa 采用 JS Entry 的方式接入微应用。将整个微应用打包成一个JS文件,发布静态资源服务器,然后在主应用中配置该 JS 文件的地址告诉 single-spa 去这个地址加载微应用。

    single-spa存在一些问题:

    • 1、对微应用的侵入性太强
      将整个微应用打包成一个 JS 文件,常见的打包优化基本上都没了,比如:按需加载、首屏资源加载优化、css 独立打包等优化措施
    • 2、样式隔离问题
      single-spa中没有做这部分的工作。如果保证一个大型项目中,主应用和微应用之间,微应用和微应用之间的样式隔离。比如应用样式以自己的应用名称开头
    • 3、JS隔离问题
      single-spa中没有做这部分的工作。JS全局对象污染,没有保证微应用A和微应用B的window互相没有影响
    • 4、资源预加载
      single-spa中没有做这部分的工作。
    • 5、应用间通信
      single-spa中没有做这部分的工作。它只在注册微应用时给微应用注入一些状态信息,后续就不管了,没有任何通信的手段,只能用户自己去实现

    4、参考文章

    微前端框架 之 single-spa 从入门到精通
    微前端框架 之 qiankun 从入门到源码分析

    相关文章

      网友评论

          本文标题:single-spa框架分析

          本文链接:https://www.haomeiwen.com/subject/lixibltx.html