qiankun 原理解析

qiankun 所实现的沙箱:

单实例:同一个时刻只有一个微应用实例存在,此刻浏览器所有浏览器资源都是这个应用独占的,方案要解决的很大程度是应用切换的时候的清理和现场恢复。比较轻量,实现起来也简单。

多实例:资源不是应用独占,就要解决资源共享的情况,比如路由,样式,全局变量读写,DOM. 可能需要考虑的情况比较多,实现较为复杂。

基座模式

在这里,我们将通过一个主应用,来管理其它子应用,它主要实现了以下的功能

应用发现。让主应用可以寻找到其它应用。 应用注册。即提供新的微前端应用,向应用注册表注册的功能。 第三方应用注册。即让第三方应用,可以接入到系统中。 访问权限等相关配置。

创建主应用

// index.js
// micro-app-main/src/main.ts
import startQiankun from './micro/';

startQiankun();

// micro/index.js
// micro-app-main/src/micro/index.ts
// 一个进度条插件
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import {
  message
} from 'ant-design-vue';
import {
  registerMicroApps,
  addGlobalUncaughtErrorHandler,
  start
} from 'qiankun';

// 微应用注册信息
import apps from './apps';

/**
 * 注册微应用
 * 第一个参数 - 微应用的注册信息
 * 第二个参数 - 全局生命周期钩子
 */
registerMicroApps(apps, {
  // qiankun 生命周期钩子 - 微应用加载前
  beforeLoad: (app) => {
    console.log('beforeMount: ', app);
    // 加载微应用前,加载进度条
    NProgress.start();
    console.log('before load', app.name);
    return Promise.resolve();
  },
  beforeMount: (app) => {
    console.log('beforeMount: ', app);
  },
  // qiankun 生命周期钩子 - 微应用挂载后
  afterMount: (app) => {
    // 加载微应用前,进度条加载完成
    NProgress.done();
    console.log('after mount', app.name);
    return Promise.resolve();
  },
  BeforeUnloadEvent: (app) => {
    console.log('app: ', app);
  }
});

/**
 * 添加全局的未捕获异常处理器
 */
addGlobalUncaughtErrorHandler((event) => {
  console.error(event);
  const {
    message: msg
  } = event;
  // 加载失败时提示
  if (msg && msg.includes('died in status LOADING_SOURCE_CODE')) {
    message.error('微应用加载失败,请检查应用是否可运行');
  }
});

// 导出 qiankun 的启动函数
export default start;


注册基座

主框架配置子应用的路由为 subApp: { url: '/subApp/**', entry: './subApp.js' },则当浏览器的地址为 /subApp/abc 时,框架需要先加载 entry 资源,待 entry 资源加载完毕,确保子应用的路由系统注册进主框架之后后,再去由子应用的路由系统接管 url change 事件。同时在子应用路由切出时,主框架需要触发相应的 destroy 事件,子应用在监听到该事件时,调用自己的卸载方法卸载应用,如 React 场景下 destroy = () => ReactDOM.unmountAtNode(container)。

//app.js
// micro-app-main/src/micro/apps.ts
// 此时我们还没有微应用,所以 apps 为空
  // 导入主应用工具类库
  import { conSjh } from '../utils/index';

  const msg = {
    utils: conSjh // 从主应用读出的工具类库
  };

const apps = [{
  name: 'ReactMicroApp',
  entry: '//localhost:9528',
  container: '#frame',
  activeRule: '#/react',
  props: msg // 将定义好的数据传递给子应用
}];

export default apps;

通信

// micro-app-main/src/shared/actions.ts
import { initGlobalState } from 'qiankun';

// 初始化 state
const initialState = {};

const actions = initGlobalState(initialState);
export default actions;
F2E

蚂蚁提出了两个原则,第一个原则是基于props以单向数据流的方式传递给子应用。第二个原则是基于浏览器原生事件做跨业务之间的通信。

通信

部署

部署

参考文章

微前端入门 可能是你见过最完善的微前端解决方案

最后更新于

这有帮助吗?