写在开头
微前端系列文章:
- 基于 qiankun 的微前端最佳实践(万字长文) - 从 0 到 1 篇
- 基于 qiankun 的微前端最佳实践(图文并茂) - 应用间通信篇
- 基于 qiankun 的微前端最佳实践(图文并茂) - 应用部署篇
- 万字长文+图文并茂+全面解析微前端框架 qiankun 源码 - qiankun 篇
本系列其他文章计划一到两个月内完成,点个 关注
不迷路。
计划如下:
- 生命周期篇;
- IE 兼容篇;
- 性能优化、缓存方案篇;
概述
本文将针对微前端框架 qiankun
的源码进行深入解析,在源码讲解之前,我们先来了解一下什么是 微前端
。
微前端
是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将单页面前端应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立开发、独立部署。同时,它们也可以在共享组件的同时进行并行开发——这些组件可以通过 NPM
或者 Git Tag、Git Submodule
来管理。
qiankun(乾坤)
就是一款由蚂蚁金服推出的比较成熟的微前端框架,基于 single-spa
进行二次开发,用于将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。(见下图)
那么,话不多说,我们的源码解析正式开始。
初始化全局配置 - start(opts)
我们从两个基础 API - registerMicroApps(apps, lifeCycles?) - 注册子应用
和 start(opts?) - 启动主应用
开始,由于 registerMicroApps
函数中设置的回调函数较多,并且读取了 start
函数中设置的初始配置项,所以我们从 start
函数开始解析。
我们从 start
函数开始解析(见下图):
我们对 start
函数进行逐行解析:
第 196 行
:设置window
的__POWERED_BY_QIANKUN__
属性为true
,在子应用中使用window.__POWERED_BY_QIANKUN__
值判断是否运行在主应用容器中。第 198~199 行
:设置配置参数(有默认值),将配置参数存储在importLoaderConfiguration
对象中;第 201~203 行
:检查prefetch
属性,如果需要预加载,则添加全局事件single-spa:first-mount
监听,在第一个子应用挂载后预加载其他子应用资源,优化后续其他子应用的加载速度。第 205 行
:根据singularMode
参数设置是否为单实例模式。第 209~217 行
:根据jsSandbox
参数设置是否启用沙箱运行环境,旧版本需要关闭该选项以兼容 IE。(新版本在单实例模式下默认支持 IE,多实例模式依然不支持 IE)。第 222 行
:调用了single-spa
的startSingleSpa
方法启动应用,这个在single-spa
篇我们会单独剖析,这里可以简单理解为启动主应用。
从上面可以看出,start
函数负责初始化一些全局设置,然后启动应用。这些初始化的配置参数有一部分将在 registerMicroApps
注册子应用的回调函数中使用,我们继续往下看。
注册子应用 - registerMicroApps(apps, lifeCycles?)
registerMicroApps
函数的作用是注册子应用,并且在子应用激活时,创建运行沙箱,在不同阶段调用不同的生命周期钩子函数。(见下图)
从上面可以看出,在 第 70~71 行
处 registerMicroApps
函数做了个处理,防止重复注册相同的子应用。
在 第 74 行
调用了 single-spa
的 registerApplication
方法注册了子应用。
我们直接来看 registerApplication
方法,registerApplication
方法是 single-spa
中注册子应用的核心函数。该函数有四个参数,分别是
name(子应用的名称)
回调函数(activeRule 激活时调用)
activeRule(子应用的激活规则)
props(主应用需要传递给子应用的数据)
这些参数都是由 single-spa
直接实现,这里可以先简单理解为注册子应用(这个我们会在 single-spa
篇展开说)。在符合 activeRule
激活规则时将会激活子应用,执行回调函数,返回一些生命周期钩子函数(见下图)。
注意,这些生命周期钩子函数属于
single-spa
,由single-spa
决定在何时调用,这里我们从函数名来简单理解。(bootstrap
- 初始化子应用,mount
- 挂载子应用,unmount
- 卸载子应用)
如果你还是觉得有点懵,没关系,我们通过一张图来帮助理解。(见下图)
获取子应用资源 - import-html-entry
我们从上面分析可以看出,qiankun
的 registerMicroApps
方法中第一个入参 apps - Array<RegistrableApp<T>>
有三个参数 name、activeRule、props
都是交给 single-spa
使用,还有 entry
和 render
参数还没有用到。
我们这里需要关注 entry(子应用的 entry 地址)
和 render(子应用被激活时触发的渲染规则)
这两个还没有用到的参数,这两个参数延迟到 single-spa
子应用激活后的回调函数中执行。
那我们假设此时我们的子应用已激活,我们来看看这里做了什么。(见下图)
从上图可以看出,在子应用激活后,首先在 第 81~84 行
处使用了 import-html-entry
库从 entry
进入加载子应用,加载完成后将返回一个对象(见下图)
我们来解释一下这几个字段
字段 | 解释 |
---|---|
template |
将脚本文件内容注释后的 html 模板文件 |
assetPublicPath |
资源地址根路径,可用于加载子应用资源 |
getExternalScripts |
方法:获取外部引入的脚本文件 |
getExternalStyleSheets |
方法:获取外部引入的样式表文件 |
execScripts |
方法:执行该模板文件中所有的 JS 脚本文件,并且可以指定脚本的作用域 - proxy 对象 |
我们先将 template 模板
、getExternalScripts
和 getExternalStyleSheets
函数的执行结果打印出来,效果如下(见下图):