**a、**当前工程提供微前端选项,并提供了基础主应用、子应用通讯方式
**b、**工程由是使用ant design pro创建,pro工程中使用的是Umi Max,本身就包含了微前端qiankun插件的能力,不需要再去添加插件。
**c、**在Umi Max中,又对qiankun插件做了一次包装,qiankun的注册、启动等接入实现被处理。只按照Umi Max 微前端的配置方式,可以很快的接入。但是:Umi Max 再次处理了qiankun后,UmiMax 提供了两种父子应用通讯方式:
父子应用间的通信有两种实现的方法:
- 基于 `useModel()` 的通信。这是 Umi **推荐**的解决方案。
- 基于配置的通信。
第一种方法,子应用都必须基于Umi开发,并且使用Umi的数据流插件
第二种方法,很难做到在任意的业务页面动态的进行父子应用的通讯
**d、**当前工程的qiankun接入时,子应用的注册、子应用时初始化数据、子应用加载处理使用了UmiMax提供的能力;父子通讯绕过了UmiMax,直接使用了qiankun插件的能力
**e、**当前文档只记录当前工程微前端接入的关键方式,其他内容请参考官方文档。
参考:
Umi Max 简介:https://umijs.org/docs/max/introduce
Umi Max 微前端:https://umijs.org/docs/max/micro-frontend
qiankun:https://qiankun.umijs.org
父应用配置:
1、配置当前应用为父应用:
// config/config.ts Umi配置
// add+
qiankun: {
master: {},
},
2、运行时注册子应用:
// app.tsx
/**
* 微前端:主应用运行时配置
* @returns
*/
export const qiankun = () => {
return {
// 微应用配置
apps: [
{
name: 'vue', // 微应用的名称
entry: '//10.50.2.128:8080', // 微应用的入口
// credentials: true, // 拉取微应用时同时拉取 Cookies
},
{
name: 'react', // 微应用的名称
entry: '//172.28.64.1:8090', // 微应用的入口
// credentials: true, // 拉取微应用时同时拉取 Cookies
},
],
// 微应用运行时的路由
routes: [
{
path: '/vue/*',
microApp: 'vue',// 指向的微应用名称
microAppProps: {
//启用子应用加载动画,默认使用Spin组件
autoSetLoading: true,
// 自定义加载动画
// loader: (loading) => <CustomLoader loading={loading} />,
// 开启子应用错误捕获能力,默认使用Result组件
autoCaptureError: true,
// 自定义的微应用错误捕获组件
// errorBoundary:(err) => <ErrorResult err={err}/>
},
},
{
path: '/react/*',
microApp: 'react',
microAppProps: {
//启用子应用加载动画,默认使用Spin组件
autoSetLoading: true,
// 自定义加载动画
// loader: (loading) => <CustomLoader loading={loading} />,
// 开启子应用错误捕获能力,默认使用Result组件
autoCaptureError: true,
// 自定义的微应用错误捕获组件
// errorBoundary:(err) => <ErrorResult err={err}/>
},
},
],
// 微前端生命周期。
/* lifeCycles: {
beforeLoad: (app: any) => {
console.log('master before load', app);
},
afterMount: (app: any) => {
console.log('master after mount', app);
},
}, */
// 开启沙箱隔离
sandbox: {
experimentalStyleIsolation: true,
},
// 预加载微应用
prefetch: true,
};
};
3、初始化qiankun微前端全局state的操作对象,在src下新建masterActions.ts文件:
父应用对微应用的数据操作、监听数据变化全部依赖于masterActions对象
import { initGlobalState, MicroAppStateActions } from 'qiankun';
/**
* 需要传给微应用的初始数据
*/
export const qiankunInitialState: Record<string, any> = {
lang: 'zh-CN',
userInfo: null,
};
// 主应用设置值:在任意地方调取该方法
/* masterActions.setGlobalState(state:Record<string, any>); */
// 主应用监听值,在任意地方调取该方法(子应用修改、主应用修改都会进入回调)
/* masterActions.onGlobalStateChange((state:Record<string, any>, prev:Record<string, any>) => {
console.log('[master] onGlobalStateChange', state, prev);
}); */
/**
* qinakun 数据操作
*/
const masterActions: MicroAppStateActions = initGlobalState(qiankunInitialState);
export default masterActions;
4、父应用透传数据给子应用:
// app.tsx
/**
* 微前端:主应用为子应用添加props state
* @returns
*/
export function useQiankunStateForSlave() {
// 子应用:使用mount生命周期中props提供的内容
/**
* return的内容会添加给子应用mount生命周期中props中
* initialGlobalState 初始值
* saveGlobalState(state: Record<string, any>) 设置值。PS:会与原来的state执行Object.assign()操作
* onGlobalStateChange((state:Record<string, any>, prev:Record<string, any>) => void) 监听值(子应用修改、主应用修改都会进入回调)
* toMasterLink(path:string) 通过主应用跳转
*/
return {
// 给子应用的初始值
initialGlobalState: qiankunInitialState,
// 给子应用的修改值方法.
// PS:子应用直接调用setGlobalState是不生效的,所以才需要这个额外的方法,这是一个坑
saveGlobalState: (state: Record<string, any>) => {
masterActions.setGlobalState(state);
},
// 子应用通过主应用跳转
toMasterLink: (path: string) => {
go(path);
},
};
}
Vue、React子应用配置:
1、子应用关键配置参照qiankun项目实践文档即可。
qiankun项目实践-React :https://qiankun.umijs.org/zh/guide/tutorial#react-%E5%BE%AE%E5%BA%94%E7%94%A8
qiankun项目实践-Vue:https://qiankun.umijs.org/zh/guide/tutorial#vue-%E5%BE%AE%E5%BA%94%E7%94%A8
2、添加子应用和父应用通讯对象,在src下新建microActions.js文件:
子应用对微应用的数据操作、监听数据变化全部依赖于microActions对象,必须在微应用mout生命周期中初始化
function emptyAction() {
// 警告:提示当前使用的是空 Action
console.error('current microActions is empty!');
}
/**
* 微应用:子应用映射mout生命周期的props内容为微应用actions
*/
class MicroActions {
/**class定义中,只设定了基础的三个属性方法,初始化后actions包含mout生命周期的props的所有内容 */
actions = {
initialGlobalState:{},
saveGlobalState:emptyAction,
onGlobalStateChange:emptyAction,
toMasterLink:emptyAction,
}
/**
* 使用子应用mout生命周期的props初始化actions
* @param {any} mountProps 子应用mout生命周期的props
*/
initActions(mountProps = {}){
this.actions = Object.assign(this.actions,mountProps);
}
/**
* 子应用监听微应用state变化(子应用修改、主应用修改都会进入回调)
* @description onGlobalStateChange((state:Record<string, any>, prev:Record<string, any>) => void)
* @param {(state:Record<string, any>, prev:Record<string, any>) => void} callback
* @param {boolean | undefined} fireImmediately 初始化就监听,默认false
* @returns
*/
onGlobalStateChange(callback, fireImmediately = false){
if(typeof callback !== 'function'){
return;
}
return this.actions.onGlobalStateChange(callback, fireImmediately);
}
/**
* 子应用设置微应用state
* @param {Record<string,any>} state
* @returns
*/
saveGlobalState(state = {}) {
return this.actions.saveGlobalState(state);
}
/**
* 子应用通过通过主应用跳转
* @param {string} path
* @returns
*/
toMasterLink(path){
if(!path){
return;
}
return this.actions.toMasterLink(path);
}
/**
* 子应用获取微应用初始state
* @returns
*/
getInitialGlobalState(){
return this.actions.initialGlobalState;
}
}
/**
* 微应用:子应用对微应用state操作
*/
const microActions = new MicroActions();
export default microActions;
3、使用父应用传入的能力,初始化子应用state actions:
// react/vue入口文件
// 这是子应用配置时入口暴露的生命周期
export async function mount(props) {
console.log('props from main framework', props);
// 该声明周期props中存在主应用透传的基础数据,初始化子应用state actions
microActions.initActions(props);
render(props);
}