一次接触微前端,还请多多指教, 目的在于学习微前端架构,理解主要原理和核心思想

主要架构

  • micro-main

    |- micro-child-vue

    |- micro-child-react

    |- micro-child-angular(持续)

    |- micro-child-common

主应用 micro-main(端口号:8086)

目前采用的是以vue-cli3搭建出来的项目为底座,后面还需要尝试以react项目为基座,接入微前端-qiankun,看看官网基本上就能跑起来,主要是分这两部

qiankun

主应用创建承载容器

容器规定了微应用的显示区域,微应用将在该容器内渲染并显示,改造App.vue,扩展vue-router

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div id="app">
<section class="main">
<div class='main-left'>
<h1>
this is Menu
</h1>
<ul>
<li><router-link to="/father">father</router-link></li>
<li><router-link to="/hello">主应用: hello world</router-link></li>
<li><router-link to="/app-vue">子应用: Vue</router-link></li>
<li><router-link to="/app-react">子应用: React</router-link></li>
</ul>
</div>
<div class="main-content">
<router-view></router-view>
<div id='frame'>
// vue 承载子应用的容器
</div>
</div>
</section>
</div>
</template>

注册微应用并启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
registerMicroApps([
{
name: 'react-app',
entry: '//localhost:3002',
container: '#frame',
activeRule: '/app-react',
},
{
name: 'vue-app',
entry: '//localhost:8086',
container: '#frame',
activeRule: '/app-vue',
props: {
childContent: 'child 主应用传给子应用',
chilName: 'cpp'
}
},
], {
beforeLoad(app) {
// 加载微应用前,加载进度条
NProgress.start();
return Promise.resolve()
},
afterMount(app) {
NProgress.done()
return Promise.resolve()
}
});
// 启动 qiankun
start();

主应用vue配置跨域

由于 qiankun 内部使用的是 Fetch HTML 的方式加载子应用,所以会遇到跨域问题。我们需要先解决跨域问题,使我们的主应用可以正常加载子应用相关资源。

在开发环境下,本项目配置了跨域解决方案,所以在直接运行项目并不会遇到跨域问题。

接入Vue微应用

主应用注册微应用

简单点就是,得有一个方式进入子应用,改动点主要是,注册微应用那里,比如想接入vue微应用,那就这样

1
2
3
4
5
6
7
8
registerMicroApps([
{
name: 'react-app',
entry: '//localhost:3002',
container: '#frame',
activeRule: '/app-react',
},
]

子应用配置微应用

vue/react/angular基本上都差不多,
首先,我们在 Vue 的入口文件 main.js 中,导出 qiankun 主应用所需要的三个生命周期钩子函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
/**
* 导出 qiankun 主应用所需要的三个生命周期钩子函数
*/
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('[qiankun] vue app bootstraped');
}
export async function mount(props) {
console.log('[qiankun] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}

还需要配置 webpack,使 main.js 导出的生命周期钩子函数可以被 qiankun 识别获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const { name } = require('./package');
console.log(name, 'pack');
module.exports = {
devServer: {
port: 8087,
headers: {
'Access-Control-Allow-Origin': '*',
},
},
configureWebpack: {
output: {
library: `${name}`,
libraryTarget: 'umd', // 把微应用打包成 umd 库格式 library 暴露为所有的模块定义下都可运行的方式
jsonpFunction: `webpackJsonp_${name}`, // 按需加载相关
},
},
};

接入React微应用

跟vue子应用差不多

微前端涉及到的相关面试

  • qiankun框架是怎么实现js 沙箱sandbox机制的(qiankun如何做到隔离),确保微应用之间 全局变量/事件 不冲突
  • HTML Entry 接入方式让你接入微应用像使用 iframe 一样简单。
  • 样式隔离,确保微应用之间样式互相不干扰。
  • 资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度(prefetch) requestIdleCallback

参考文档