背景:

  • 通过网上各种《微前端学习资料》 学习,对微前端了解到深入,入门可以看《如何设计实现微前端框架 - qiankun》、也通过官网了解
  • 推荐看这本书 《前端架构:从入门到微前端》,它教会我在搭建脚手架和实现架构会遇到哪些挑战,如何才能正确的规避这些。
  • 从加入公司,了解项目,重构项目,再到改造项目,不断地在新旧系统之间切换,使得为了更好设计一个架构。
  • 只有经历过遗留系统,才能让自己真正地成长。
  • 你清楚了解微前端是什么后,就可以深入进入到开发,理论还不如自己动手干,对于你是技术leader,我建议你可以了解微前端的底层如 single-spa,我这里可以提供《从零实现微前端框架》《带你手写微前端框架》,因为我们接下来使用的qiankun, 它就是一个基于 single-spa微前端实现库。可以通过最小demo来了解qiankun的生态圈,这里我也可以通过 《qiankun 微前端方案实践及总结》,可以找到常见的问题,也可以从官网获取常见问题
  • 上手一个新技术,总会遇到各种问题,可以看官网、github issues ,实在解决不了的问题,可以在钉钉找队友解决,反正我开发下来,这些问题都可以通过这些方式找到解决方案的。

    Vue+Qiankun+Websocket 云平台后端系统 (winstack 信创云平台)

    项目简介

WinStack是一个可堆叠的轻量级云平台,包含WinSphere、WinStore、WinFabric及其他自研或第三方组件模块,融合计算、存储、网络、运维等功能的一体化管理。
Winstack项目由多项目组合起来,如kv、winstore、安全中心、存储、运维、网络、系统多个模块,像kv项目使用 angular技术, winstore、安全中心 使用 vue技术。

  • 微服务架构

    • 管理平台采用先进的微服务架构进行设计开发,可拆分成多个解耦的模块并独立提供服务。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的,可以独立开发演化、运行和扩展,实现平台组件化、松耦合、自治、去中心化,快速与企业现有系统集成以及迭代上线新特性。

      项目截图

      登录页面
      image.png
      首页
      image.png
      公共左侧菜单
      image.png
      kv模块
      image.png
      winstore模块
      image.png
      安全模块
      image.png

      技术栈

  • 前端:后端系统pc端,vue全家桶,ant-design-vue组件库,Echarts.js,Less,wh-components内部业务组件库,Websocket,qiankun技术栈

    项目构建

    前端在vue-cli3基础上开发,在此之上根据项目需求对项目工程作出几点修改,前端代码在view/文件夹中

  • 请求拦截器:在view/src/request/中,基于axios提供的interceptors对所有ajax的请求和响应添加相应操作,如请求头添加,token添加,响应后台错误状态码的识别与报错;封装axios请求,主要为get,post两种。

  • 导航守卫:在view/src/router/中,做了全局导航守卫,未登录用户只能访问项目登录页面。
  • 工具类:在view/src/utils/中,对常用枚举值、全局组件注册、常用类封装等功能做模块化封装。
  • css样式:在view/src/style/中,全局公共样式,初始化样式。
  • svg组件:在view/src/icons/中,封装用于svg展示组件,用做小icon的展示,svg保存该文件夹中。
  • 模块化:对路由与vuex做模块化封装。
  • 国际化:i18n
  • 主题色:

    开发前的准备以及遇到技术问题

    1.微前端技术预研材料微前端框架设计

  1. 微前端入门到实践 《微前端入门到实践》
  2. 《微前端学习资料》

    2.微前端子项目搭建过程

  3. 《vue-template》这是一个vue 模板,开箱即用

  • 在使用模板过程,可以借鉴 vue-element-admin文档
  1. 开始开发时,可以把项目当成单独项目开发,待项目完成后,在接入到主应用

    3.微前端打包和编译说明

    查看 《微前端开发指南》

    4.菜单路由跳转说明(包含vue和angular两种)

    查看 《微前端开发指南》

    5.嵌入angularjs旧项目说明

    winstack项目由多项目组合起来,如kv、winstore、安全中心、存储、运维、网络、系统多个模块,像kv项目使用 angular技术, winstore、安全中心 使用 vue技术
    kv项目虽然是一个单页面angular 老项目,如果要改造微应用,相对比较麻烦,需要改动地方比较多,所以鉴于以上问题。就决定用微应用去加载iframe kv项目,如点击虚拟化资源菜单先去加载app-vue-kv应用,iframe会加载kv 指定路径url。

iframe方案
iframe 大家都很熟悉,使用简单方便,提供天然的 js/css 隔离,也带来了数据传输的不便,一些数据无法共享(主要是本地存储、全局变量和公共插件),两个项目不同源(跨域)情况下数据传输需要依赖 postMessage 。
iframe 有很多坑,但是大多都有解决的办法:

  1. 页面加载问题

iframe 和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载,阻塞 onload 事件。每次点击都需要重新加载,虽然可以采用 display:none 来做缓存,但是页面缓存过多会导致电脑卡顿。(无法解决)

  1. 布局问题

iframe 必须给一个指定的高度,否则会塌陷。
解决办法:子项目实时计算高度并通过 postMessage 发送给主页面,主页面动态设置 iframe 高度。有些情况会出现多个滚动条,用户体验不佳。

  1. 弹窗及遮罩层问题

弹窗只能在 iframe 范围内垂直水平居中,没法在整个页面垂直水平居中。

  • 解决办法1:通过与框架页面消息同步解决,将弹窗消息发送给主页面,主页面来弹窗,对原项目改动大且影响原项目的使用。
  • 解决办法2:修改弹窗的样式:隐藏遮罩层,修改弹窗的位置。
  1. iframe 内的 div 无法全屏

弹窗的全屏,指的是在浏览器可视区全屏。这个全屏指的是占满用户屏幕。
全屏方案,原生方法使用的是 Element.requestFullscreen(),插件:vue-fullscreen。当页面在 iframe 里面时,全屏会报错,且 dom 结构错乱。
解决方案:iframe 标签设置 allow=”fullscreen” 属性即可

  1. 浏览器前进/后退问题

iframe 和主页面共用一个浏览历史,iframe 会影响页面的前进后退。大部分时候正常,iframe 多次重定向则会导致浏览器的前进后退功能无法正常使用。并且 iframe 页面刷新会重置(比如说从列表页跳转到详情页,然后刷新,会返回到列表页),因为浏览器的地址栏没有变化,iframe 的 src 也没有变化。

  1. iframe 加载失败的情况不好处理

非同源的 iframe 在火狐及 chorme 都不支持 onerror 事件。

  • 解决办法1:onload 事件里面判断页面的标题,是否 404 或者 500
  • 解决办法2:使用 try catch 解决此问题,尝试获取 contentDocument 时将抛出异常。

解决办法参考:stackoverflow上的问题:Catch error if iframe src fails to load

不要对 iframe 抱有偏见,它也是微前端的一种实现方式,如果页面上无弹窗、无全屏等操作,iframe 也是很好用的。配置缓存和 cdn 加速,如果是内网访问,也不会很慢。 iframeqiankun 可以并存,jQuery 多页应用使用 iframe 接入就挺好,什么时候什么场景该用哪种方案,具体情况具体分析

6.嵌入iframe高度自适应逻辑

第一种:部分页面是这样做
iframe 必须给一个指定的高度,否则会塌陷。
解决办法:子项目实时计算高度并通过 postMessage 发送给主页面,主页面动态设置 iframe 高度。有些情况会出现多个滚动条,用户体验不佳。
第二种:
看app-vue-kv view/VirtualizedResources.vue 页面,通过加个setInterval 定时器,动态获取 可视高度
setInterval
el.contentWindow.document.getElementById(“bodyid”).scrollHeight

// 有时候一套方法不可能兼容所有的问题,
// 在不同分配率下,呈现效果不一样的,布局变化
// window.screen.width 获取可视化宽度,对不同的分配率下设置不同的高度

7.外层全局搜索通知到iframe内部实现说明

看app-vue-kv view/VirtualizedResources.vue 页面
使用 window.postMessage 实现跨源通信
// 主main

  1. let iframeWin = this.$refs["mapFrame"].contentWindow;
  2. iframeWin.postMessage(dataObj, "*");

// iframe
// 监听主main 传递的message

  1. window.addEventListener("message",function(e){
  2. //todo
  3. })

8.全局websocket消息做了哪些改造

主要src/mixins、App.vue、app-vue-login App.vue

  1. 切换子应用后,接收到消息,在顶部消息数据显示不更新,在mixin 里,直接存在data,然后通过watch监听taskList,在存到vuex this.$store.commit(“websocket/SET_TASK_ARR”, newVal);
  2. App.vue 这里面主要处理是,this.buildConnect(); 建立websocket 连接,判断是否已经退出登录后,中断websocket 连接
  3. app-vue-login App.vue this.$root.parentVuex.dispatch(“commonData/setListern”); // 保证登录页面不建立连接,中断连接

    9.主应用与微应用通信方式

  4. initGlobalState(state)

qiakun 提供了一个全局的 GlobalState 来共享数据。主项目初始化之后,子项目可以监听到这个数据的变化,也能提交这个数据。
一般用法:
全局状态,用于项目中的不同框架的通信,但是如果你项目用的都是vue,就没有必要使用这个了。demo
image.png

  1. 第二种就是 项目用的都是vue, 通过 props 传递父项目的 Vuex 。react 也是如此

main/micro-app.js

  1. const microApps = [
  2. {
  3. name: "app-vue-login",
  4. entry: isProd ? "/child/app-vue-login/" : "//localhost:9529",
  5. activeRule: getActiveRule("#/app-vue-login"),
  6. props: { data: { store, router } }
  7. },
  8. ]

app-vue-login main.js

  1. function render({ data = {}, container } = {}) {
  2. router = new VueRouter({
  3. routes
  4. });
  5. instance = new Vue({
  6. router,
  7. store,
  8. data() {
  9. return {
  10. parentRouter: data.router,
  11. parentVuex: data.store
  12. };
  13. },
  14. render: (h) => h(App)
  15. }).$mount(container ? container.querySelector("#appVueHash") : "#appVueHash");
  16. }
  1. this.$root.parentVuex.commit("commonData/SET_USER_INFO", {
  2. userInfo: response,
  3. });

vue 项目之间数据传递还是使用共享父组件的 Vuex 比较方便,与其他技术栈的项目之间的通信使用 qiankun 提供的 GlobalState 。

对项目建议

全面拥抱 TypeScript

  1. TypeScript 目前可谓大红大紫,根据 2018 stateofjs,超过 50% 的使用率以及 90% 的满意度,甚至连 Facebook 的 Jest 也正在从 Flow 切换到 TS。如果你还没有使用,可以考虑切换,绝对能给项目带来很大提升。
  2. TS 最大的优势是它提供了强大的静态分析能力,结合 TSLint 能对代码做到更加严格的检查约束。传统的 EcmaScript 由于没有静态类型,即使有了 ESLint 也只能做到很基本的检查,一些 typo 问题可能线上出了 Bug 后才被发现。
  3. 用TS开发的工具库等。
  4. TypeScript 来提升代码健壮性和可维护性

自己在主导新技术落地,需要考虑: 无论是对于从头开发的微前端应用,还是正在迁移的微前端应用,这种架构的演进都需要一个实施时间。出于以下目的,我们需要快速“发布”MRV版本(最小可发布版本)的微前端架构应用: ◎ 架构在项目中的可行性验证。 ◎ 向领导和团队证明架构的可能性。 ◎ 增强团队对于新技术的信心。 将那个最小的、成本最低的应用迁移到微前端架构中。