type
status
date
slug
summary
tags
category
icon
password
微前端(micro-app)
引言
随着Web应用复杂度的增加,传统的前端开发模式面临着维护难度大、开发效率低等问题。微前端技术应运而生,通过将大型前端应用拆分为多个独立的子应用,提升了代码的可维护性和开发效率。本文将介绍微前端技术的基本概念,并使用 micro-app 框架展示如何构建模块化的Web应用。
微前端技术概述
什么是微前端
微前端是一种架构风格,相比传统 Iframe 嵌套实现的模块化,它借鉴了后端微服务的成功经验,将若干可单独开发和部署的中小型前端应用,无缝集成为一个高复杂度的大型前端应用,同时又保留了流畅的用户体验、极快的加载速度和更好的开发体验。通过这种方式,微前端不仅能提高应用的可维护性和扩展性,还增强了团队的协作效率和整体开发速度。
微前端架构的核心思想:
- 不同业务需求场景下各类框架开发的子应用,可以轻松的融合为一
- 融合后不同团队仍然可以独立负责各自的子应用,进行开发、部署、运行
micro-app 简介
micro-app
是由京东前端团队推出的一款微前端框架,它借鉴了WebComponent的思想,通过js沙箱
、样式隔离
、元素隔离
、路由隔离
模拟实现了ShadowDom的隔离特性,将微前端封装成一个类WebComponent组件,从而实现微前端的组件化渲染,使用简单、功能强大、兼容所有框架是它的主要优势。工作原理
快速使用
- 安装依赖
- 注册并初始化
- 在基座嵌入子应用
Vue:
React:
- 在子应用配置跨域支持
以大数据中心为例
从快速使用可以看出,micro-app 的引入极其简单,与 Iframe 相似。
Weshyper 大数据中心是一个聚合了多个子应用模块搭建的大数据平台,其主要采用了 Iframe 进行模块嵌套开发,因此也遇到了 Iframe 带来的许多常见缺陷,如子应用切换加载缓慢、本地存储跨域、面页弹框不居中、数据通信繁琐,路由跳转难控制等问题。
现在我们其中的子应用 Dgovern-web 为例,尝试使用 micro-app 进行替换
关于路由
micro-app 实现了一套虚拟路由系统,使子应用可以运行在这套虚拟路由系统中,从而与主应用的路由隔离
其中包含五种路由模式,通过
router-mode
选项进行配置:- search:默认模式,路由信息会作为 query 参数挂在浏览器地址上,但易出现循环刷新,不推荐
- native:会放开主应用和子应用的路由隔离,路由跳转显示上更直观,但易出现冲突,不推荐
- native-scope:和 native 一样,但路由地址的域名会指向子应用,而不是主应用,不推荐
- pure:子应用路由独立渲染,不影响地址显示,也不增加路由堆栈,更像是组件,推荐
- state:基于浏览器 history.state 进行渲染的路由模式,表现和 iframe 类似,但却没有 iframe 存在的问题,推荐
这里 Dgovern-web 选择采用 pure 模式
路由跳转
主应用控制子应用跳转
Dgovern-web 通过监听主应用路由变化,读取其中预存的重定向地址后,再通知子应用进行路由跳转
可以看出,切换后的子应用路由跳转仅用一行代码就解决了,并且也不需要在子应用中进行额外的监听操作
子应用控制主应用跳转
主应用
子应用
子应用认证
通常通过 Iframe 嵌套的子应用做认证,需要在主应用登录后把获取到统一认证的 token 主动发送给子应用,子应用接收到 token 后存储,再尝试跳转到首页或重定向页,Dgovern-web 中是这样处理的
Dgovern-web 通过获取主应用传递的 URL 查询参数,拿到了 token 和 redirect 重定向地址,并将 token 存储到 localStorage 中,以供后续随时使用。
之所以需要这么麻烦的传递 token,是因为 Iframe 同源策略导致主应用与子应用的
localStorage
被隔离。切换为 micro-app 后,我们测试发现子应用的 localStorage 并未与主应用隔离, 在子应用中可以任意读取主应用中的本地存储,测试如下
主应用
子应用
因此,子应用可以避免执行外部免登录过程,从而直接使用主应用中存储的 token
认证后的默认页
通常情况下,当经过认证后的应用首次加载,会路由跳转到首页,但作为子应用,我们需要其首次加载后默认跳转到主应用所选菜单页,micro-app 提供了子应用的默认渲染首页设置项,通过
defaultPage
指定配合计算属性,Dgovern-web 可轻松处理每个导航的默认加载首页
数据通信
在使用 Iframe 时,数据通信只能使用浏览器提供的
postMessage
接口实现,这是一个低级别的通信方式,需要开发者自行处理消息的发送、接收和解析。micro-app 针对性的提供了
dispatch
方法,实现了更为简洁、格式规范、内置安全机制的数据通信子应用向主应用发送数据
子应用
主应用
可以看到,dispatch 与 postMessage 写法上基本相似,但 dispatch 的第二个参数是一个回调函数,它的入参是主应用处理完消息后的返回值,这无疑提供了便捷的数据交互
主应用向子应用发送数据
发现的问题
标签标题
micro-app 的标签标题默认加载的是各自应用的所设置的 document.title
这是因为 microApp 对 documet 的代理处理过程并没有处理 document.title,所以子应用中可以通过
document.title = 'xxx'
改变基座的站点标题在微前端模式下,通常更希望由基座统一负责设置站点标题,不希望受到子应用的干扰
解决方案是通过给title设置一个空函数,来忽略 document.title 执行
资源加载失败
micro-app 对子应用的资源路径会自动补全其所在的域名,但对于某些框架和库在特定场景下创建的元素无法被拦截和处理。如 element-ui 打包后生成的字体资源文件,在加载时会出现404的情况。
解决方案是在运行时动态设置
webpack.publicPath
首先在子应用src目录下创建名称为
public-path.js
的文件,并添加如下内容然后在 main.js 入口文件中最顶部引入
- Author:风之旅人
- URL:https://www.hrmi.fun//article/micro-app-dg
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!