Vue qiankun微前端实现详解
作者:Cytra
引言
前端时间有个契机,让我们团队开始进行微前端的相关实践。
最近正好有些成果了,来一个阶段性的总结,也方便后续进一步的开发。
可能第一次听说微前端的同学都会不明觉厉,那么ta到底是个啥?本章会从以下3个角度阐述我的理解:
- What:微前端是什么
- Why:为什么选择微前端
- How:微前端实践
What:微前端是什么
首先,微前端其实并不高大上,它的本质十分简单:
一句话介绍:在一个应用中展示另几个应用的界面。
是不是看起来与iFrame
非常类似?
在微前端体系中,被展示的应用称为子应用,而提供展示容器的应用称为主应用。
Why:为什么选择微前端
这个问题我觉得可以从两个方面来回答:
- 微前端能做到什么
- 为什么不使用iFrame
微前端能做到什么
随着公司规模不断扩大,项目团队数量不断增加,我们不可避免的遇到了这些问题:
- 多个项目需要同一个能力模块
- 项目团队都有自己的特色模块,这些模块可能是别的项目团队想要的
- 各个团队使用的技术栈有所区别,迁移成本较大
- 开发新项目时,可能需要某些老项目的能力模块
- …………
这些问题,归根结底就是技术复用。
我们想,能不能将每个团队的特色模块划分为子应用。大家都基于主应用开发,当路径切换时加载不同的子应用,这样每个子应用都是独立的,技术栈也就不用再做限制了!
为什么不使用iFrame
如果不考虑体验问题,iframe 几乎是最完美的微前端解决方案了。--qiankun文档
iframe 最大的特性就是提供了浏览器原生的硬隔离方案,不论是样式隔离、js 隔离这类问题统统都能被完美解决。但他的最大问题也在于他的隔离性无法被突破,导致应用间上下文无法被共享,随之带来的开发体验、产品体验的问题:
- Url 不同步。在iFrame中刷新会导致应用出错、后退前进按钮无法使用、无法使用统一的标签导航……
- UI 不同步,DOM 结构不共享。iFrame中难以构建一个带有全局遮盖的弹窗。
- 全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求实现困难。
How:微前端实践
抛开需求讲技术完全就是耍流氓,所有架构最终都是为了业务。
在我的认知中,微前端更适合构建控制台类的单页面应用。会打开多个页面的社区、论坛类应用是不适合使用微前端的。既然都打开新页面了,为什么不直接跳转到另一个项目的地址呢。
团队选择了qiankun@2.0作为微前端的实现方案,qiankun官方网站:qiankun.umijs.org/zh
跟着官网的Demo,只需要两步就可以实现微前端模式改造:
- 在主应用增加注册子应用的代码
- 在子应用中提供钩子函数
在主应用中注册微应用
在main.js等项目入口文件处注册子应用:
import { registerMicroApps, start } from 'qiankun'; registerMicroApps([ { name: 'react app', // app name registered entry: '//localhost:7100', container: '#yourContainer', activeRule: '/yourActiveRule', }, { name: 'vue app', entry: { scripts: ['//localhost:7100/main.js'] }, container: '#yourContainer2', activeRule: '/yourActiveRule2', }, ]); start();
当微应用信息注册完之后,一旦浏览器的 url 发生变化,便会自动触发 qiankun 的匹配逻辑,所有 activeRule 规则匹配上的微应用就会被插入到指定的 container 中,同时依次调用微应用暴露出的生命周期钩子。
在子应用导出相应的生命周期钩子
微应用需要在自己的入口 js (通常就是你配置的 webpack 的 entry js,在我们项目中是main.js)
导出 bootstrap、mount、unmount 三个生命周期钩子,以供主应用在适当的时机调用。
/** * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。 */ export async function bootstrap() { console.log('react app bootstraped'); } /** * 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法 */ export async function mount(props) { ReactDOM.render(<App />, props.container ? props.container.querySelector('#root') : document.getElementById('root')); } /** * 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例 */ export async function unmount(props) { ReactDOM.unmountComponentAtNode( props.container ? props.container.querySelector('#root') : document.getElementById('root'), ); } /** * 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效 */ export async function update(props) { console.log('update props', props); }
结尾
由于实际上的项目比Demo复杂的多,实际开发过程中遇到了一万个坑,包括路由、权限、第三方插件等等,这部分的内容会在后续帖子里更新。
以上就是Vue qiankun微前端实现详解的详细内容,更多关于Vue qiankun微前端的资料请关注脚本之家其它相关文章!