一文搞懂微前端

一. 微前端的背景和动机

单页应用

单页应用往往是一个庞大的前端项目,由一个团队或多个团队共同开发,使用同一套技术栈,打包成一个整体,部署在一个域名下

随着 Web 应用的功能越来越丰富和复杂,单页应用不得不面临以下问题:

  • 技术栈的选择和升级受限,难以适应不同的业务需求和技术发展。
  • 项目的可维护性和可测试性降低,代码的耦合度高,模块的划分不清晰,变更的风险大。
  • 项目的构建和发布效率低下,打包的体积大,加载的时间长,部署的频率低。

开发和维护成本也越来越高,为了解决这些问题,微前端的概念应运而生。

微前端

将一个大型的前端应用拆分成多个小型的前端应用,每个前端应用可以由不同的团队开发,使用不同的技术栈,独立部署,最后在一个统一的入口进行聚合展示。这样,每个前端应用可以专注于自己的业务领域,实现高内聚,低耦合,提高开发效率和质量。

优点

  • 技术栈无关,让不同的团队可以使用自己熟悉的技术开发和部署子应用;
  • 维护成本低,独立开发、独立部署,提高开发效率和灵活性;
  • 应用之间的高效解耦,避免业务模块间的耦合导致的复杂性和风险;
  • 平滑迁移和升级框架和系统,提升用户体验和满意度。

缺点

  • 额外的开发、学习成本,需要设计和实现一套微前端的框架和协议;
  • 通信和协作问题,需要定义和遵守应用之间的一套通信规范和接口;
  • 隔离和安全问题,需要考虑应用之间样式隔离、沙箱隔离、权限控制等方面;
  • 一致性和可用性问题,需要保证应用的风格统一、版本一致、错误处理等方面

二. 微前端的实现方案和框架

实现微前端的方案有多种,主要可以分为以下几类:

  • 路由分发式:通过路由将不同的业务分发到不同的独立前端应用上,通常通过 HTTP 服务的反向代理或者浏览器端的路由拦截来实现。这种方案的优点是简单易实现,缺点是应用间的切换会有页面刷新,用户体验不佳。
  • iframe 嵌套式:通过 iframe 将不同的前端应用嵌套在一个主应用中,实现应用间的隔离和集成。这种方案的优点是兼容性好,隔离性强,缺点是 iframe 有很多限制,如布局,跨域,通信,性能等问题。
  • Web Components 组件式:通过 Web Components 标准将不同的前端应用封装成自定义元素,然后在主应用中使用这些元素,实现应用间的组合和复用。这种方案的优点是符合 Web 标准,组件化程度高,缺点是兼容性差,需要 polyfill 支持,而且有一定的学习成本。
  • 组合式应用路由分发式:通过在主应用中动态加载和渲染不同的前端应用,实现应用间的无缝切换和集成。这种方案的优点是用户体验好,技术栈无关,缺点是实现难度高,需要解决应用间的路由,隔离,通信等问题。

目前,市面上已经有一些成熟的微前端框架,如 single-spa,qiankun,icestark 等,它们都是基于组合式应用路由分发微前端的方案,提供了一些通用的能力和接口,帮助开发者快速搭建微前端系统。

三. 微前端的常见问题:

  • 路由系统:如何实现子应用的切换和卸载,以及主框架和子应用之间的路由协调。一种解决方案是使用 single-spa 库,它提供了一套基于 url 的路由机制,可以动态加载和卸载子应用,同时支持多种技术栈的集成¹²。
  • 资源加载:如何实现子应用的动态加载和隔离,以及主框架和子应用之间的资源共享。一种解决方案是使用 HTML Entry 的方式,即将子应用打包成一个 HTML 文件作为入口,主框架通过 fetch html 的方式获取子应用的静态资源,并将 HTML document 插入到主框架的容器中。
  • 状态管理:如何实现子应用之间的通信和数据共享,以及主框架和子应用之间的状态同步。一种解决方案是使用自定义事件或全局变量的方式,实现跨应用的事件监听和数据传递,同时避免状态的滥用和污染。
  • 样式隔离:如何实现子应用的样式不影响主框架和其他子应用,以及主框架和子应用之间的样式统一。一种解决方案是使用 Shadow DOM 或 CSS Modules 的方式,实现样式的作用域隔离,同时遵循一套统一的 UI 设计规范和主题变量。

-----------------------------------------进阶部分 以下主要以qiankun为例--------------------------------

微前端的路由分发机制

根据浏览器的 URL 变化来切换不同的微应用,以及在微应用之间同步路由状态。一般来说,微前端的路由分发机制可以分为两种模式:hash 模式和 history 模式。

hash 模式是指使用 URL 的 hash(#)部分来标识不同的微应用,例如 http://example.com/#/app1/foo 表示 app1 应用的 foo 路由,http://example.com/#/app2/bar 表示 app2 应用的 bar 路由。这种模式的优点是实现简单,兼容性好,缺点是不利于 SEO,而且 hash 的长度有限制。

history 模式是指使用 URL 的 pathname(/)部分来标识不同的微应用,例如 http://example.com/app1/foo 表示 app1 应用的 foo 路由,http://example.com/app2/bar 表示 app2 应用的 bar 路由。这种模式的优点是 URL 更美观,更利于 SEO,缺点是需要服务端的支持,而且实现复杂度高。

无论是哪种模式,微前端的路由分发机制都需要解决以下几个问题:

  • 如何在主应用中识别和匹配微应用的路由
  • 如何在主应用中激活和切换微应用
  • 如何在微应用中获取和更新路由状态
  • 如何在主应用和微应用之间保持路由一致性

对于第一个问题,一种常见的做法是在注册微应用时,指定一个匹配规则,例如正则表达式,函数,或者字符串,来判断当前的 URL 是否属于某个微应用。例如,qiankun 提供了一个 activeRule 参数,可以是一个正则表达式,如 /app1/,也可以是一个函数,如 location => location.pathname.startsWith('/app1'),来确定是否激活 app1 应用。

对于第二个问题,如何在主应用中激活和切换微应用,一种常见的做法是使用 single-spa 的 startnavigateToUrl 方法,来启动微前端系统,以及在不同的微应用之间跳转。例如,qiankun 在主应用中调用 start() 方法,来初始化微前端系统,然后在主应用的导航栏中,使用 navigateToUrl 方法,来实现微应用的切换,如 navigateToUrl('/app1/foo')

对于第三个问题,如何在微应用中获取和更新路由状态,一种常见的做法是使用浏览器的 history API,来监听和修改 URL 的变化,以及使用 location 对象,来获取当前的 URL 信息。例如,qiankun 在微应用中调用 history.pushStatehistory.replaceState 方法,来更新 URL 的 pathname 部分,以及使用 location.pathname 属性,来获取当前的 pathname 值。

对于第四个问题,如何在主应用和微应用之间保持路由一致性,一种常见的做法是使用 popstate 事件,来监听 URL 的变化,以及使用 window 对象,来获取当前的 URL 信息。例如,qiankun 在主应用和微应用中都注册了 popstate 事件的监听器,来响应 URL 的变化,以及使用 window.location 对象,来获取当前的 URL 信息。

微前端的应用隔离策略

微前端的应用隔离策略是指如何保证不同的微应用之间不会相互干扰,造成全局变量,样式,事件等的冲突。一般来说,微前端的应用隔离策略可以分为以下几种:

  • JS 沙箱:通过代理或重写全局对象,如 windowdocumentlocalStorage 等,来实现微应用的 JS 隔离。例如,qiankun 使用了 Proxy 对象,来拦截对全局对象的访问和修改,以及使用了 snapshot 方法,来保存和恢复全局对象的状态。
  • CSS 隔离:通过添加命名空间,作用域,或者 Shadow DOM,来实现微应用的 CSS 隔离。例如,qiankun 使用了 prefix 参数,来给微应用的样式添加一个前缀,以及使用了 shadow 参数,来给微应用创建一个 Shadow DOM。
  • DOM 隔离:通过添加容器元素,或者 Shadow DOM,来实现微应用的 DOM 隔离。例如,qiankun 使用了 container 参数,来给微应用指定一个容器元素,以及使用了 shadow 参数,来给微应用创建一个 Shadow DOM。

微前端的消息通信方式

微前端的消息通信方式是指如何在主应用和微应用之间,以及在不同的微应用之间,进行数据的传递和同步。一般来说,微前端的消息通信方式可以分为以下几种:

  • props 传递:通过在主应用中给微应用传递一些属性,来实现数据的传递。例如,qiankun 提供了一个 props 参数,可以是一个对象,如 { name: 'app1' },也可以是一个函数,如 () => ({ name: 'app1' }),来给微应用传递一些属性。
  • 事件广播:通过在主应用和微应用中使用自定义事件,来实现数据的广播和订阅。例如,qiankun 提供了一个 emit 方法,来在主应用中触发一个自定义事件,如 emit('foo', 'bar'),以及一个 on 方法,来在微应用中监听一个自定义事件,如 on('foo', data => console.log(data))
  • 全局状态:通过在主应用中维护一个全局状态对象,来实现数据的共享和同步。例如,qiankun 提供了一个 initGlobalState 方法,来在主应用中初始化一个全局状态对象,如 const { onGlobalStateChange, setGlobalState } = initGlobalState({ count: 0 }),以及一个 getMicroAppStateActions 方法,来在微应用中获取一个全局状态对象的操作方法,如 const { onGlobalStateChange, setGlobalState } = getMicroAppStateActions()

微前端适用场景

微前端的适用场景有以下几个:

  • 大型复杂的 Web 应用,如电商,门户,企业级等,需要支持多个业务领域,多个团队,多个技术栈,多个版本等。
  • 需要进行应用的重构或者迁移,如从老旧的技术栈迁移到新的技术栈,或者从单体应用拆分成微服务等。
  • 需要提高应用的开发效率和质量,如实现敏捷开发,持续集成,持续交付等。

结语

微前端是一种前沿的 Web 应用架构模式,它可以帮助开发者将一个庞大的前端应用拆分成多个小型的前端应用,实现技术栈的自由选择,业务模块的独立开发,应用部署的快速迭代,以及应用架构的增量演进。微前端也有一些挑战和限制,需要开发者根据自己的实际情况,选择合适的方案和框架,以及解决应用间的路由,隔离,通信等问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QMLfor python pyside6

QML QML是一种用于创建用户界面的声明性语言,它是Qt生态系统中的一部分。QML使用JavaScript语言和其独特的语法来定义用户界面组件,使得开发人员可以轻松地创建现代化、漂亮而又响应迅速的应用程序。 QML是基于QtQuick技术构建的,QtQuick是…

【JavaScript】3.4 JavaScript在现代前端开发中的应用

文章目录 1. 用户交互2. 动态内容3. 前端路由4. API 请求总结 JavaScript 是现代前端开发的核心。无论是交互效果,还是复杂的前端应用,JavaScript 都发挥着关键作用。在本章节中,我们将探讨 JavaScript 在现代前端开发中的应用,包…

上门服务系统|东郊到家软件提供高效服务的科技支柱

预约上门服务系统的崛起改变了传统服务行业的格局。用户不再需要亲自前往实体店面,而是通过几次点击就能享受到各类服务。这背后离不开预约上门服务系统的智能化和高效性,而源码正是这个系统的灵魂所在。下面小编就给大家介绍下上门服务系统开发优势。 1…

Gavin Wood:财库保守主义偏离了初心,应探索 Fellowship 等更有效的资金部署机制

波卡创始人 Gavin Wood 博士最近接受了 The Kusamarian 的采访,分享了他的过往经历、对治理的看法,还聊到了 AI、以太坊、女巫攻击、财库等话题。本文整理自 PolkaWorld 对专访编译的部分内容,主要包含了 Gavin 对治理、财库提案、生态资金分…

人工智能_机器学习056_拉格朗日乘子法原理推导_公式由来详解_原理详解---人工智能工作笔记0096

https://blog.csdn.net/Soft_Po/article/details/118332454 这里有老师的一篇文章介绍拉格朗日乘子法的原理推导 结合老师的这篇文章我们来看一下详细的推导过程 可以看到上一节我们说,一个有条件的,函数,可以转换为一个,无条件的函数, 根据拉格朗日乘子法,可以创建出一个等…

uc_09_创建新进程 exec() system()

1 什么是创建新进程(夺舍) 在前面文章中,我们学习了fork()函数用来创建子进程。 子进程是父进程的副本,复制父进程除代码段以外的其他数据,代码段数据和父进程共享。 子进程的PID与父进程不同: 而创建新进程则不同。 与fork()不同…

docker-compose;私有镜像仓库harbor搭建;镜像推送到私有仓库harbor

docker-compose;私有镜像仓库harbor搭建;镜像推送到私有仓库harbor 文章目录 docker-compose;私有镜像仓库harbor搭建;镜像推送到私有仓库harbordocker-compose私有镜像仓库harbor搭建镜像推送到私有仓库harbor docker-compose D…

论坛自动多播放源采集源码

论坛自动多播放源采集源码是一种用于自动抓取论坛中的多个视频播放源的程序源代码。它可以自动搜索并采集论坛中的多个视频播放源,帮助用户快速找到所需的视频资源。该源码可以帮助用户节省时间和精力,提高视频资源的获取效率。 演示 地 址:…

2023年小美赛认证杯A题太阳黑子预测(Sunspot Forecasting)思路模型代码解析

2023年小美赛认证杯A题:太阳黑子预测(Sunspot Forecasting) 【请电脑打开本文链接,扫描下方名片中二维码,获取更多资料】 一、问题重述 太阳黑子是太阳光球上的现象,呈暂时性斑点,比周围区域…

2023年中国金融科技研究报告

第一章 行业概况 1.1 定义 金融科技(FinTech, Financial Technology)代表了金融和技术的交汇。这一领域虽然处于发展的初期阶段,但已经展现出深远的影响力。金融科技的业务模式多样,涵盖了从传统金融服务的数字化转型到新兴技术…

python中的序列类型

文章目录 字符串列表元组由元组构成的列表 字符串 字符串是编程语言中的一种基本数据类型,用于表示一串字符序列。在Python中,字符串是不可变的,也就是说一旦字符串被创建,就无法修改其中的字符。 Python中的字符串可以用单引号…

索尼mxf覆盖部分恢复案例(索尼PMW-580)

索尼mxf覆盖部分恢复案例(索尼PMW-580) 索尼的摄像机型号是比较繁多的,高端系列基本上是以mxf文件为主,这一类案例之前处理不少,今天我们看一个索尼pmw-580摄像机删除后又覆盖的恢复案例。 故障存储:64G SD卡/Exfat文件系统 故障现象: 拍…

【开发规范】前端开发中引用文件的方式

1. 介绍 在前端开发中,使用别名引用文件和使用相对路径引用文件是两种不同的方式,它们通常用于引用模块、组件或资源文件。这两种方式的区别主要在于它们的含义和用途。 2. 使用别名引用文件 符号通常是一种别名,表示项目的根路径或者某个特…

Kettle 浅入浅出

前言 最近又要迭代客户定制化的数据处理系统了。提到数据处理,不禁想到了以前使用过的 ETL 处理工具 Kettle。本文将对 Kettle 做一些简单的介绍。 Kettle 介绍 在介绍 Kettle 前先了解下什么是 ETL,ETL 是 Extract-Transform-Load 的缩写&#xff0c…

Django回顾1

目录 1.c/s架构 2.b/s架构 3.基于socket写一个web应用 main.py index.html 4.手写web框架 main.py login.html time.html user_list.html user_list_new 二.HTTP协议 1.什么是HTTP协议 2.HTTP协议的作用 3.HTTP版本及区别 4.HTTP协议的特点 5.HTTP请求协议 常…

腹泻的原因,种类,风险因素,如何预防

谷禾健康 腹泻是常见的健康问题,相信绝大多数人在生活中都曾遭受过腹泻的困扰。 根据2016年柳叶刀期刊统计,慢性腹泻影响全世界 3%-20% 的成年人。全球每年有17亿儿童腹泻病例,腹泻是五岁以下儿童死亡的第五大原因,每年约有52.5万…

P1 什么是链表 C语言简单易懂

目录 前言 01 什么是链表 02 数组的特点 03 数组的缺点 3.1 删除数组其中一个元素 3.2 数组增加某个节点 04 链表 前言 🎬 个人主页:ChenPi 🐻推荐专栏1: 《 C 》✨✨✨ 🔥 推荐专栏2: 《 Linux C应用编程(概念…

如何在Ubuntu上清理缓存和垃圾文件

随着时间的推移,Ubuntu系统上可能会积累大量的缓存和垃圾文件,占据宝贵的磁盘空间,同时也可能影响系统性能。为了确保系统保持高效运行并释放磁盘空间,我们可以定期执行清理操作。在本文中,我们将介绍一些常见的清理步…

Leetcode98 验证二叉搜索树

题意理解: 首先明确二叉树的定义,对于所有节点,根节点的值大于左子树所有节点的值,小于右子树所有节点的值。 注意一个误区: 根节点简单和左孩子,右孩子比大小是不够的,要和子树比,…

2024年天津天狮学院专升本专业课考试报名通知

天津天狮学院2024年高职升本科专业课报名时间考试时间通知 1.报名条件 报名条件和具体要求按照天津市招生委员会的文件规定执行。考生必须完成文化课报名环节,且填报天津天狮学院志愿,方可报考我校专业课考试。考生提供的各种证件应真实有效&#xff0…