
❝前沿:前半年微前端火得一踏糊涂,恰好业务需求上有这样的应用场景,针对目前的微前端解决方案作了技术选型,qiankun做为蚂蚁金服内部孵化出来的微前端解决方案,通过线上应用充分检验及打磨最后开源,最终选择qiankun做为咱们云产品架构入口。不过官方文档上关于上线部署文档较少,不少童鞋也可能只是在本地玩玩,没有到真正走通整个闭环,因而结合自身,在将qiankun落地过程当中遇到的“那些坑”作个梳理。但愿对你有所帮助css
❞
1.🍵 茶前点心
❝本文不大篇幅介绍关于qiankun的“前世此生”,更多的设计理念介绍请看文档若是有想了解其余微前端解决方案的童鞋,也能够回顾下以前树酱分享的微前端那些事html
❞
举个例子:咱们有个这样的场景,我有个门户Portal的登录界面(主应用基座),登录成果后能够切换不一样的子应用,以下有两个子应用A和B,且都在以前是独立部署的,单独能够访问,可是咱们如今想借助qiankun把他们“嵌”到基座来加载,往下看实操前端
你可能会问直接用iframe不香吗?真不香,主要几个局限问题vue
-
父子应用之间通讯问题 -
cookie共享问题(可作单点登录SSO) -
交互视图效果不佳

上面是一个经过域名访问子应用的示意图,接下来咱们看看一个view视图,header头部和sideMenu左侧菜单是属于portal门户的,而右侧区域则是显示切换子应用的视图,预期效果:当咱们访问dev.portal.com/a
该域名时(即切换到子应用A),左侧菜单也会根据不一样应用切换不一样数据nginx

1.1 注册子应用时应该注意哪些问题?
❝👦 啊明同窗:qiankun是如何注册子应用的呢?web
❞
qiankun是经过registerMicroApps(apps, lifeCycles)
API来注册子应用的,详细文档请看点我👉 用来实现当浏览器 url 发生变化时,自动加载相应的子应用的功能,结合上面的例子咱们试着在基座main.js注册子应用vue-cli
主要包括:api
-
entry
: 子应用的 entry 地址,好比咱们如今有两个子应用A和B,那么这里配置的就是他们的资源访问域名或ip -
render
:本质上是container的转换,container用来定义子应用的容器节点的选择器或者 Element 实例,这里使用的是实际例子 -
activeRule
:子应用的激活规则,即什么路由访问才会去fetch entry配置的域名或ip,咱们用了getActiveRule
来完成匹配,咱们看看getActiveRule
的实现,该函数经过传入当前 location 做为参数,而后根据函数返回数值来看,若返回值为 true 时则代表当前子应用会被激活,则去调用entry入口配置

匹配以下跨域
✅ https://dev.portal.com/a
✅ https://dev.portal.com/a/anything/everything
🚫 https://dev.portal.com/c
匹配成功后,qiankun 经过 fetch 去获取所匹配子应用的静态资源浏览器
1.2 资源访问跨域如何解决?
❝👦 啊呆同窗:你这样不会跨域吗?基座 https://dev.portal.com/ 获子应用a的资源 https://dev.monitor.com/a的资源 ,根据浏览器同源策略(浏览器采用同源策略,禁止页面加载或执行与自身来源不一样的域的任何脚本)应该获取不到吧,明显跨域
❞
答案:是,因为 qiankun 是经过 fetch 去获取子应用注册时配置的静态资源url,全部静态资源必须是支持跨域的,那就得设置容许源了,简单的设置能够看下面

-
Access-Control-Allow-Origin
:跨域在服务端是不容许的。只能经过给Nginx配置Access-Control-Allow-Origin *
后,才能使服务器能接受全部的请求源(Origin) -
Access-Control-Allow-Headers
: 设置支持的Content-Type
1.3 子应用加载失败是什么问题?
❝👦 啊明同窗:跨域解决了,可仍是fetch不到子应用a的静态资源?是什么问题咋搞?
❞
出现这个报错:Application died in status LOADING_SOURCE_CODE: You need to export the functional lifecycles in xxx entry
答案:你的打包姿式不对
❝vue-cli 3x项目中须要经过在vue.config.js配置output来配置输出的方式,以下👇所示
❞

-
pubilcPath
: 主要解决的是子应用动态载入的 脚本、样式、图片 等地址不正确的问题 -
output.library
:须要与主应用注册子应用时的name一致且惟一 -
output.libraryTarget:umd
: 导出umd格式,能够支持inport、require和script引入
而后建立一个publichPath文件,并在main.js 引入

1.4 子应用的publichPath到底应该怎么配置?
❝👦 啊明同窗:打包output配置改好了,可是为何publichPath路径配置为/a?
❞
拓展: 沿用上文提到的a应用的访问域名 dev.monitor.com/a
如今浏览器要正确获取a应用的静态资源中的css文件,则会去访问 dev.monitor.com/a/css/common.css
主要分两种状况:
-
publichPath若是默认配置或者配置为/,则生成的index.html 访问的资源是则不正确,由于将访问的是dev.monitor.com/css/common.css并非a应用的资源 -
配置为/a,则生成的index.html 访问的资源是 就能够

❝👦 啊呆同窗:那publichPath路径配置为
❞./
相对路径能够吗?
答案:也是能够的,跟配置为/a
访问同样
1.5 如何保障原来的应用运行正常,但能集成到基座portal中
❝👦 啊明同窗:我以前a应用是单独运行部署的,我经过qiankun集成到基座portal中会有影响吗?
❞
答案:使用这个全局变量来区分当前是否运行在 qiankun 的主应用中
那就是:window.__POWERED_BY_QIANKUN_
那能够用来干吗?请看下面👇

-
独立运行: window.__POWERED_BY_QIANKUN__
为false,执行mount建立vue对象 -
运行在qiankun: window.__POWERED_BY_QIANKUN__
为true,则不执行mount
1.6 父应用如何共享util和data给子应用
❝👦 隔壁老王同窗:若是我想把门户登录应用登录成功获取到的我的数据共享给子应用还有一些公用的方法,我该怎么作?
❞
答案:能够在注册子应用的时候,把定义好要共享的msg,经过props共享出去

-
msg.data
把store状态管理数据共享给子应用 -
msg.prototype
定义一些原型数据,好比是否为qiankun上下文中
父应用定义完,那子应用是如何获取呢?是经过在子应用挂载前,将props数据导到子应用经过遍历赋值给到子应用vue原型中
1.7 history路由模式,须要如何配置ngnix,才能正常访问?
❝👦 啊宇同窗:我看你访问的路由模式不是hash,而是history模式,那你是怎么解决当页面刷新404问题?
❞
答案:经过nginx配置加入try_files,history 模式一样会有一个问题,就是当页面刷新时,若是没有合适的配置,会出现404错误,针对这种请看,须要额外在nginx配置,对于找不到url的,将首页html返回

-
try_files:用来解决nginx找不到client客户端所须要的资源时访问404的问题
-
proxy_pass:主要是用来配置接口网关反向代理,可使得父子应用下访问的api是一致的,防止接口跨域问题
公众号:前端食堂
掘金:童欧巴
知乎:童欧巴
这是一个终身学习的男人,他在坚持本身热爱的事情,欢迎加入前端食堂,和这个男人一块儿开心的变胖~
推荐阅读:
据说你 ping 用的很 6 ?给我图解一下 ping 的工做原理!
在看和转发是莫大鼓励❤️
本文分享自微信公众号 - 前端食堂(webcanteen)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。