微前端框架 qiankun 全面解析到源码实现

  • 微前端(Micro Frontends)是一种将大型前端应用拆分为多个独立模块的架构设计思想,旨在解决复杂应用开发与维护的难题。qiankun 是目前流行的微前端解决方案之一,基于 single-spa 进行封装,提供了一种简单且完整的微前端架构实践。

微前端概念与优势

  1. 什么是微前端
  • 微前端类似于后端的微服务架构,将一个大型的前端应用拆分为多个独立的前端模块,每个模块可以独立开发、测试、部署和运行。每个子应用(微应用)可以使用不同的技术栈,如 React、Vue、Angular 等。
  1. 微前端的优势
  • 独立开发:每个微应用可以由独立的团队开发,甚至可以使用不同的技术栈,降低团队间的耦合度。
  • 渐进迁移:在技术更新或重构过程中,可以通过逐步替换微应用来实现平滑迁移,而不是一次性更新整个系统。
  • 独立部署:每个微应用可以独立部署,减少部署时的影响面。
  • 复用性高:微应用可以在不同项目间复用,减少重复开发的工作。

qiankun 简介

  • qiankun 是基于 single-spa 实现的微前端框架,它通过提供完整的生命周期管理、应用间通信机制以及对沙箱的支持,简化了微前端的开发和集成。
  1. qiankun 特点
  • 简单易用:对 single-spa 进行了封装,开发者不需要关心底层细节,只需按照简单的 API 使用即可。
  • 无技术栈限制:支持任意框架(React、Vue、Angular 等)的微应用接入。
  • 沙箱隔离:通过沙箱机制隔离不同微应用的全局变量、样式,确保互不干扰。
  • 应用通信机制:支持主应用与微应用之间的数据传递与通信,提供灵活的 API。

qiankun 核心概念

  1. 主应用(Master App)
  • 主应用是整个微前端系统的宿主应用,负责微应用的注册、加载和调度。主应用通常使用统一的框架(如 React 或 Vue)进行开发。
  1. 微应用(Sub App)
  • 微应用是独立开发的前端模块,可以在主应用中注册和运行。每个微应用可以独立运行,也可以在主应用中加载时与其他微应用协同工作。
  1. 应用生命周期
  • qiankun 提供了标准的生命周期钩子,包括 bootstrap、mount、unmount,分别对应应用的初始化、挂载和卸载过程。
  1. 沙箱机制
  • qiankun 通过沙箱机制隔离不同微应用的运行环境,确保它们之间的全局变量和样式互不影响。
  1. 应用间通信
  • qiankun 提供了简单的 API 用于主应用与微应用之间进行数据传递和事件通

基本使用

  1. 安装 qiankun
  • 在主应用中安装 qiankun:
npm install qiankun --save
  1. 主应用配置
import { registerMicroApps, start } from 'qiankun';

// 注册微应用
registerMicroApps([
  {
    name: 'app1',
    entry: '//localhost:7100', // 子应用的访问地址
    container: '#container', // 子应用挂载的 DOM 节点
    activeRule: '/app1', // 子应用激活的路径
  },
  {
    name: 'app2',
    entry: '//localhost:7200',
    container: '#container',
    activeRule: '/app2',
  },
]);

// 启动微前端
start();
  1. 微应用配置
  • 在每个微应用中,你需要导出标准的生命周期钩子:
export async function bootstrap() {
  console.log('微应用启动');
}

export async function mount(props) {
  console.log('微应用挂载', props);
}

export async function unmount() {
  console.log('微应用卸载');
}

qiankun 的高级功能

  1. 沙箱与样式隔离

qiankun 通过沙箱机制实现对微应用的全局变量和样式隔离,确保不同的微应用不会相互干扰。每个微应用的运行环境是相互独立的。

  1. 应用间通信
    qiankun 提供了 initGlobalState 和 onGlobalStateChange API,用于微应用与主应用之间共享数据和通信。
// 主应用中创建全局状态
import { initGlobalState } from 'qiankun';
const actions = initGlobalState({ user: 'admin' });

actions.onGlobalStateChange((state, prev) => {
  console.log('状态变化', state, prev);
});

// 微应用中使用全局状态
props.onGlobalStateChange((state, prev) => {
  console.log('子应用状态变化', state, prev);
});
  1. 动态加载微应用
  • qiankun 支持动态注册和加载微应用,可以根据业务需求在运行时决定是否加载某个微应用。
import { loadMicroApp } from 'qiankun';

const microApp = loadMicroApp({
  name: 'app3',
  entry: '//localhost:7300',
  container: '#container',
  props: { someProp: 'someValue' },
});

// 动态卸载微应用
microApp.unmount();
  1. 多实例应用
  • qiankun 支持多实例的微应用,可以在同一页面上运行同一个微应用的多个实例。

源码分析

  • qiankun 是基于 single-spa 封装的微前端解决方案,旨在提供更加简单、开箱即用的微前端架构。通过对 qiankun 源码的分析,能帮助我们更好地理解其工作原理及微前端的核心思想。本文将逐步分析 qiankun 源码的核心部分,包括微应用的注册、加载、沙箱机制、应用间通信等。
  1. 源码结构概览

qiankun 的核心代码主要包括以下模块:

  • registerMicroApps:微应用的注册、管理模块。
  • start:微前端的启动模块。
  • loadMicroApp:微应用的动态加载模块。
  • 沙箱机制:隔离微应用的全局变量和样式。
  • 应用间通信:主应用和微应用之间的状态管理。
src
├── globalState // 应用间状态管理
├── interfaces  // 类型声明和接口定义
├── sandbox     // 沙箱隔离机制
├── utils       // 工具方法
├── index.ts    // 核心注册与启动代码
├── start.ts    // start 函数,启动微前端
└── register.ts // registerMicroApps 函数,注册微前端应用

  • registerMicroApps 是 qiankun 的核心 API,负责将微应用注册到主应用中。其源码位于 register.ts 文件。
export function registerMicroApps(
  apps: Array<RegistrableApp<any>>,
  lifeCycles?: FrameworkLifeCycles<any>,
) {
  // 对微应用的配置进行标准化
  const unmountPromises = apps.map((app) => {
    return validateRegistrableApp(app);
  });

  // 传递到 single-spa 中注册微应用
  unmountPromises.forEach((promise) => {
    promise.then((appConfig) => {
      registerApplication(appConfig);
    });
  });
}
  1. 启动微前端:start
  • 在 start.ts 文件中,start 方法用于启动微前端环境。它会触发微应用的加载,并控制应用的生命周期。
export function start(opts: StartOptions = {}) {
  // 启动 single-spa
  startSingleSpa(opts);

  // 初始化沙箱
  if (opts.sandbox) {
    initializeSandbox(opts.sandbox);
  }

  // 启动全局状态管理
  if (opts.globalState) {
    initializeGlobalState(opts.globalState);
  }
}

qiankun 使用 single-spa 管理应用的生命周期,而 start 方法会通过 startSingleSpa 启动整个微前端架构,并根据配置初始化沙箱机制和全局状态管理。

  1. 沙箱机制
  • 沙箱机制是 qiankun 的核心之一,它通过隔离不同微应用的全局变量和样式,确保应用之间互不干扰。qiankun 的沙箱模块位于 src/sandbox 中,主要包括 ProxySandbox 和 LegacySandbox 两种沙箱实现。
  • proxySandbox 使用现代浏览器的 Proxy API 来隔离全局对象。这是 qiankun 默认的沙箱实现方式。
export class ProxySandbox {
  private updatedValueSet = new Set<string>();
  private sandboxRunning = false;
  private proxy: WindowProxy;

  constructor() {
    const rawWindow = window;
    const fakeWindow = Object.create(null);

    this.proxy = new Proxy(fakeWindow, {
      get(target, key) {
        return key in target ? target[key] : rawWindow[key];
      },
      set(target, key, value) {
        target[key] = value;
        if (this.sandboxRunning) {
          this.updatedValueSet.add(key);
        }
        return true;
      }
    });
  }

  // 启动沙箱
  activate() {
    this.sandboxRunning = true;
  }

  // 停止沙箱
  deactivate() {
    this.sandboxRunning = false;
  }
}

  • 激活沙箱:调用 activate() 方法时,Proxy 开始拦截对 window 对象的修改。
  • 停止沙箱:调用 deactivate() 方法后,所有全局对象的修改将不再生效。
  1. LegacySandbox
  • LegacySandbox 是为不支持 Proxy 的浏览器设计的沙箱实现。它通过手动保存和恢复全局变量的方式来实现隔离。
export class LegacySandbox {
  private originalWindowProperties: Map<string, any>;

  constructor() {
    this.originalWindowProperties = new Map();
  }

  // 记录原始全局变量
  recordOriginalState() {
    Object.keys(window).forEach((key) => {
      this.originalWindowProperties.set(key, window[key]);
    });
  }

  // 恢复原始全局变量
  restoreOriginalState() {
    this.originalWindowProperties.forEach((value, key) => {
      window[key] = value;
    });
  }
}

  • 这类沙箱实现比较粗糙,性能上不如 ProxySandbox,但能兼容旧浏览器。
  1. 应用间通信
  • qiankun 提供了全局状态管理器 GlobalState,用于主应用和微应用之间的数据通信。
  • initGlobalState 用于初始化全局状态,并提供 setGlobalState 和 onGlobalStateChange 方法,用于跨应用通信。
export function initGlobalState(initialState: Record<string, any>) {
  let state = initialState;

  function setGlobalState(newState: Record<string, any>) {
    state = { ...state, ...newState };
    // 通知所有订阅者
    subscribers.forEach((listener) => listener(state));
  }

  function onGlobalStateChange(listener: (state: any) => void) {
    subscribers.push(listener);
    return () => {
      subscribers = subscribers.filter((item) => item !== listener);
    };
  }

  return {
    setGlobalState,
    onGlobalStateChange,
  };
}
  • setGlobalState: 设置新的全局状态,所有应用会自动收到更新。
  • onGlobalStateChange: 订阅状态变化的监听器,微应用可以通过它获取主应用的数据更新。
  1. loadMicroApp 动态加载微应用
  • loadMicroApp 是 Qiankun 提供的用于动态加载微应用的方法,允许在运行时按需加载微应用,而不需要在应用启动时注册。
export function loadMicroApp(
  appConfig: LoadableApp<any>,
  opts?: FrameworkConfiguration,
) {
  // 加载微应用
  const microApp = loadApp(appConfig, opts);

  // 启动微应用
  microApp.mount();

  return microApp;
}
  • 通过 loadMicroApp,开发者可以在特定场景下按需加载微应用,而无需一开始就注册所有应用。这样可以减小主应用的初始加载体积,提升性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/888597.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【小沐学GIS】blender导入OpenTopography地形数据(BlenderGIS、OSM、Python)

文章目录 1、简介1.1 blender1.2 OpenStreetMap地图 2、BlenderGIS2.1 下载BlenderGIS2.2 安装BlenderGIS2.3 申请opentopography的key2.4 抓取卫星地图2.5 生成高度图2.6 获取OSM数据 结语 1、简介 1.1 blender https://www.blender.org/ Blender 是一款免费的开源 3D 创作套…

【c++】初步了解类和对象2

1、类的作用域 类定义了一个新的作用域&#xff0c;类的所有成员都在类的作用域中。在类体外定义成员时&#xff0c;需要使用 :: 作用域操作符指明成员属于哪个类域。 如图&#xff0c;此时在类内声明了函数firstUniqChar()&#xff0c;在类外进行了函数体的具体定义。 但是却…

使用 classification_report 评估 scikit-learn 中的分类模型

介绍 在机器学习领域&#xff0c;评估分类模型的性能至关重要。scikit-learn 是一个功能强大的 Python 机器学习工具&#xff0c;提供了多种模型评估工具。其中最有用的函数之一是 classification_report&#xff0c;它可以全面概述分类模型的关键指标。在这篇文章中&#xff…

国庆作业

day1 1.开发环境 Linux系统GCCFDBmakefilesqlite3 2.功能描述 项目功能: 服务器&#xff1a;处理客户端的请求&#xff0c;并将数据存入数据库中&#xff0c;客户端请求的数据从数据库进行获取&#xff0c;服务器转发给客户端。 用户客户端&#xff1a;实现账号的注册、登…

加密软件有哪些?2024年十大好用的企业文件加密软件大盘点

随着数字化转型的加速&#xff0c;企业面临的数据安全威胁日益增加。为防止敏感数据泄露&#xff0c;企业文件加密已成为保护公司机密信息的必要手段。以下是2024年十大好用的企业文件加密软件大盘点&#xff0c;帮助企业在复杂的数字环境中确保数据安全。 1.安秉加密软件 安秉…

Navicat下载安装

官网地址&#xff1a;Navicat | Download Navicat Premium 14-day trial versions for Windows, macOS and Linux 1、进入官网下载地址&#xff0c;根据需求进行下载 2、双击安装程序&#xff0c;点击【下一步】 3、选择【我同意】&#xff0c;点击下一步 4、自定义安装路径&a…

基于Dify的工作流简单测试

文章目录 工作流定义工作流构建新建工作流任务分解任务分类任务执行日常聊天任务执行计算字符串长度的三次幂任务执行获取ip地址任务执行其他任务不执行 变量汇集结果返回效果展示 工作流定义 下面是工作流官方文档中给出的工作流定义&#xff0c;其实工作流与Agent调用的对象…

java:pdfbox 3.0 去除扫描版PDF中文本水印

官网下载 https://pdfbox.apache.org/download.html下载 pdfbox-app-3.0.3.jar cd D:\pdfbox 运行 java -jar pdfbox-app-3.0.3.jar java -jar pdfbox-app-3.0.3.jar Usage: pdfbox [COMMAND] [OPTIONS] Commands:debug Analyzes and inspects the internal structu…

《Windows PE》4.3 延迟加载导入表

延迟加载导入表&#xff08;Delayed Import Table&#xff09;是PE文件中的一个数据结构&#xff0c;用于实现延迟加载&#xff08;Lazy Loading&#xff09;外部函数的机制。 延迟加载是指在程序运行时&#xff0c;只有当需要使用某个外部函数时才进行加载和绑定&#xff0c;…

Llama系列上新多模态!3.2版本开源超闭源,还和Arm联手搞了手机优化版,Meta首款多模态Llama 3.2开源!1B羊驼宝宝,跑在手机上了

Llama系列上新多模态&#xff01;3.2版本开源超闭源&#xff0c;还和Arm联手搞了手机优化版&#xff0c;Meta首款多模态Llama 3.2开源&#xff01;1B羊驼宝宝&#xff0c;跑在手机上了&#xff01; 在多模态领域&#xff0c;开源模型也超闭源了&#xff01; 就在刚刚结束的Met…

VSCode运行QT界面

VSCode用久了,感觉Qt Creator的写起代码来还是不如VSCode得心应手,虽然目前还是存在一些问题,先把目前实现的状况做个记录,后续有机会再进一步优化。 当前方式 通过QtCreator创建一个CMake项目,然后使用CMake的方式在VSCode中进行编译。 claude给出的建议 左上角的名字会…

C++ 算法学习——1.6 前缀和与二维前缀和算法

前缀和算法&#xff08;Prefix Sum Algorithm&#xff09;&#xff1a; 概念&#xff1a;前缀和算法通过在遍历数组时计算前缀和&#xff08;从数组的第一个元素开始累加到当前元素的和&#xff09;&#xff0c;可以在O(1)时间内得到任意区间的子数组和&#xff0c;而不需要重复…

详解 PDF 转 JPG:简单操作,高效转换

如今&#xff0c;众多软件都已具备将PDF转换为JPG的功能&#xff0c;所以pdf怎么转换成jpg图片已经不难解决了吧。接下来&#xff0c;我想分享几款依然保存在我电脑中&#xff0c;且非常实用的PDF转JPG工具给大家。 1.福昕PDF转换大师 链接一下>>https://www.pdf365.cn…

【2024年10月测试通过】conda下使用虚拟环境安装最新版pytorch2.4+cuda12.4

开头先说重点&#xff1a; 1.采用conda的虚拟环境&#xff0c;会在沙盒环境下安装好所有所需包&#xff0c;而且该虚拟环境拷贝给其他人员可以直接用&#xff0c;很方便。 2.pytorch官网访问不了&#xff0c;有一个国内镜像推荐&#xff0c;地址为PyTorch - PyTorch 中文 3.…

OXO:一款针对Orchestration框架的安全扫描引擎

关于OXO OXO是一款针对Orchestration框架的安全扫描引擎&#xff0c;该工具可以帮助广大研究人员检测Orchestration安全问题&#xff0c;并执行网络侦查、 枚举和指纹识别等操作。 值得一提的是&#xff0c;OXO还提供了数十种其他的协同工具&#xff0c;包括网络扫描代理&…

erlang学习:Linux命令学习10

从百度网盘下载文件 共享百度网盘获得链接 https://pan.baidu.com/s/1iUOTAWr1SRlL2fBZ7lIV拿到链接之后在浏览器中进行下载&#xff0c;可以查看下载链接 右键这些文件即可得到下载链接 类似于长这样 https://bdbl-cm01.baidupcs.com/file/b02f72906b3d0d07130be625eabc76…

出海快报 | “三消+短剧”手游横空出世,黄油相机“出圈”日本市场,从Q1看日本手游市场趋势和机会

编者按&#xff1a;TopOn出海快报栏目为互联网出海从业者梳理出海热点&#xff0c;供大家了解行业最新发展态势。 1.“三消短剧”横空出世&#xff0c;融合创新手游表现亮眼 随着竞争的加剧&#xff0c;新产品想要突出重围&#xff0c;只能在游戏中加入额外的元素。第一次打开…

java复制查询数组-cnblog

java数组 复制数组 copyOf(待复制数组,复制后新数组的长度) 如果复制后数组的长度&#xff0c;长于原来数组&#xff0c;多出来的元素会被补0&#xff0c;如果新数组元素少会从第一个元素&#xff0c;取到指定元素长度 package nb;import java.util.Arrays;public class co…

行业预测 60TB 硬盘将于 2028 年到来

在硬盘容量增长停滞了一段时间后&#xff0c;在短短四年内从目前的 30TB 增长到 60TB 将是一个巨大的增长。 然而&#xff0c;这正是 IEEE 最新发布的《海量数据存储设备和系统国际路线图》报告所预测的。 该路线图预计 2028 年市场上将出现 60TB 的硬盘驱动器。 这一增长将由一…

Flet介绍:平替PyQt的好用跨平台Python UI框架

随着Python在各个领域的广泛应用&#xff0c;特别是在数据科学和Web开发领域&#xff0c;对于一个简单易用且功能强大的用户界面&#xff08;UI&#xff09;开发工具的需求日益增长。传统的Python GUI库如Tkinter、PyQt虽然功能强大&#xff0c;但在易用性和现代感方面略显不足…