亲宝软件园·资讯

展开

Vue qiankun微前端

Cytra 人气:0

引言

前端时间有个契机,让我们团队开始进行微前端的相关实践。

最近正好有些成果了,来一个阶段性的总结,也方便后续进一步的开发。

可能第一次听说微前端的同学都会不明觉厉,那么ta到底是个啥?本章会从以下3个角度阐述我的理解:

What:微前端是什么

首先,微前端其实并不高大上,它的本质十分简单:

一句话介绍:在一个应用中展示另几个应用的界面。

是不是看起来与iFrame非常类似?

在微前端体系中,被展示的应用称为子应用,而提供展示容器的应用称为主应用

Why:为什么选择微前端

这个问题我觉得可以从两个方面来回答:

微前端能做到什么

随着公司规模不断扩大,项目团队数量不断增加,我们不可避免的遇到了这些问题:

这些问题,归根结底就是技术复用

我们想,能不能将每个团队的特色模块划分为子应用。大家都基于主应用开发,当路径切换时加载不同的子应用,这样每个子应用都是独立的,技术栈也就不用再做限制了!

为什么不使用iFrame

如果不考虑体验问题,iframe 几乎是最完美的微前端解决方案了。--qiankun文档

iframe 最大的特性就是提供了浏览器原生的硬隔离方案,不论是样式隔离、js 隔离这类问题统统都能被完美解决。但他的最大问题也在于他的隔离性无法被突破,导致应用间上下文无法被共享,随之带来的开发体验、产品体验的问题:

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复杂的多,实际开发过程中遇到了一万个坑,包括路由、权限、第三方插件等等,这部分的内容会在后续帖子里更新。

加载全部内容

相关教程
猜你喜欢
用户评论