qiankun

本文档主要对qiankun进行一个整体性的概述,让开发者有一个系统的主应用,微应用的概念,加快对框架的理解使用。

前端概念示意图

在这里插入图片描述

qiankun简单介绍

下图是qiankun开发团队对微前端的提出的方案设计,最终产出物就是qiankun
在这里插入图片描述

  • 基于 single-spa 封装,提供了更加开箱即用的 API
  • 技术栈无关,任意技术栈的应用均可 使用/接入,不论是 React/Vue/Angular/JQuery 还是其他等框架。
  • HTML Entry 接入方式。接入微应用像使用 iframe 一样简单
  • 样式隔离,确保微应用之间样式互相不干扰。
  • JS 沙箱,确保微应用之间 全局变量/事件 不冲突。
  • 资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。
  • umi 插件,提供了 @umijs/plugin-qiankun 供 umi 应用一键切换成微前端架构系统。

使用场景

  • 项目很多,规模很大,都是每个项目独立使用git此类仓库维护的、技术栈为vue/react/angular的这类应用
  • 需要整合到统一平台上,你正在寻找可能比iframe更合适的替代方案
  • 项目A有功能A1、A2、A3,项目B有功能B1、B2、B3,产品经理要你把A2、B1、B3组合成一个包含这些功能的新项目

基本使用方式

主应用与微应用

  • 直观来讲,上面示意图中的某平台代表的就是主应用,项目A,项目B...等代表各个子应用。
  • 主应用应该是包含了系统中的公共部分例如:菜单栏、登录、退出等功能;
  • 微应用则是为满足业务需求所开发的多数子项目,需要区分的是微应用和组件的区别,组件是为了满足单一模块的功能,组件组件之间可以根据业务进行通信等,而微应用则是一个完整独立的项目,所以如果关联紧密存在频繁通信的嘤应用应该做成一个微应用。

生命周期

微应用需要在自己的入口 js (通常就是你配置的 webpack 的 entry js) 导出 bootstrap、mount、unmount三个生命周期钩子,以供主应用在适当的时机调用。

  • bootstrap:只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。通常可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等

    export async function bootstrap() {
      console.log('react app bootstraped');
    }
    
  • mount: 应用每次进入都会调用 mount 方法,通常在这里触发应用的渲染方法

    export async function mount(props) {
      console.log(props);
      ReactDOM.render(<App />, document.getElementById('react15Root'));
    }
    
  • unmount: 应用每次 切出/卸载 会调用的方法,通常在这里卸载微应用的应用实例

    export async function update(props) {
      console.log('update props', props);
    }
    

项目通信

  • qiankun提供: initGloabalState(state) 定义全局状态,并返回通信方法,官方建议在主应用使用,微应用通过 props 获取通信方法。

  • 简单示例:

    主应用:

    import { initGloabalState, MicroAppStateActions } from 'qiankun';
    
    // 初始化 state
    const actions: MicroAppStateActions = initGloabalState(state);
    
    actions.onGlobalStateChange((state, prev) => {
      // state: 变更后的状态; prev 变更前的状态
      console.log(state, prev);
    });
    actions.setGlobalState(state);
    actions.offGlobalStateChange();
    

    微应用:

    export async function mount(props) {
      const { container, onGlobalStateChange, setGlobalState } = props;
      onGlobalStateChange((state, prev) => {
        // state: 变更后的状态; prev 变更前的状态
        console.log(state, prev);
      }, true);
      setGlobalState({
        ignore: props.name,
        user: {
          name: props.name,
        },
      });
    }
    

Demo

这里建议本地跑一下官方的Demo,进一步了解

git clone https://github.com/umijs/qiankun.git

需要注意的点

  • 业务关联紧密的功能单元应该做成一个微应用,反之关联不紧密的可以考虑拆分成多个微应用。 一个判断业务关联是否紧密的标准:看这个微应用与其他微应用是否有频繁的通信需求。
  • Vue技术栈的话可能需要处理一些问题,例如:因为多个vue实例在同一个document里,需要避免全局变量污染、全局监听污染、样式污染等,需要制定接入规范等
  • 微应用不宜拆分过细,建议按照业务域来做拆分。
  • 微应用的 package.json 中的 name 字段是否是微应用中唯一的。
  • 由于 qiankun 是通过 fetch 去获取微应用的引入的静态资源的,所以必须要求这些静态资源支持跨域。

以前仅为前期调研过程,后续随着实际应用会持续更新

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐