特价专区

微前端架构全面解析:什么是微前端及其主流解决方案

首页旅行打工度假生活技术关于工具简历导出🇨🇳首页旅行技术生活打工度假关于工具👩‍💻微前端架构全面解析:什么是微前端及其主流解决方案published_date最新编辑 2025年04月08日summarize本文深入解析了微前端架构的概念与原理,详细介绍了微前端如何帮助大型应用进行拆分与管理。文章包括了常见的微前端技术方案如qiankun、single-spa及Web Components的介绍,并重点讨论了这些技术如何实现应用隔离、组件共享和通信。对于前端开发者、架构师及团队管理者,本文提供了全面的微前端架构知识。tagsWebsiteWEBSITE:https://www.jessieontheroad.com/GitHub:https://github.com/Jessie-jzn微前端是什么?为什么要使用微前端?微前端就是一个软件架构的设计理念,目的是使大型的应用系统能够更好进行拆分和管理。传统的前端应用程序往往随着功能的增加而变得庞大臃肿,维护和更新变得困难。微前端通过将前端应用程序拆分成更小的、独立的部分,每个部分都能够独立开发、部署和维护,从而降低了整体系统的复杂度。这些独立的部分可以是由不同团队开发的,它们之间可以使用不同的技术栈,也可以独立地进行版本管理和发布。微前端可以帮助团队更快地开发新功能,降低应用程序的维护成本,并促进团队之间更好的合作。主流微前端解决方案qiankun 基于single-spasingle-spa是一个用于构建多个独立前端应用程序并在同一页面上运行它们的js微前端框架,single-spa 提供了一套灵活的 API 和机制,使得各个前端应用程序可以独立开发、部署和维护,同时能够协同工作并共享资源qiankun 则在 single-spa 的基础上进行了封装和扩展,提供了更便捷的微前端开发体验和更强大的功能提供基座模式,用于注册、承载、启动子应用,子应用可以是单独的项目提供单实例,多实例,应用通信,应用隔离等microApp 基于web ComponentsWeb Components 是一种浏览器标准,允许创建可重用的自定义 HTML 元素,这些元素封装了 HTML、CSS 和 JavaScript,并具有良好的封装性和隔离性microApp 利用了 Web Components 的特性,将前端应用程序拆分成多个独立的微应用,每个微应用都是一个独立的 Web Component实现步骤定义微应用: 将整个前端应用程序拆分成多个独立的微应用。每个微应用可以是一个 Web Component,封装了自己的 HTML、CSS 和 JavaScript 代码,并定义了自己的入口点和功能。注册微应用: 在微前端的主应用程序中,注册所有的微应用。这通常涉及指定微应用的入口点、路由信息和其他配置。动态加载微应用: 当需要加载某个微应用时,主应用程序可以动态地从远程服务器或本地加载相应的 Web Component,并将其插入到页面中。通信与集成: 微应用之间可能需要进行通信和集成,以实现共享数据或共同工作。可以使用诸如 Custom Events、PostMessage 等技术来实现微应用之间的通信。独立部署和维护: 每个微应用都可以独立地进行部署和维护,因为它们都是独立的 Web Component。这使得团队可以更灵活地开发和发布新功能,而不会影响其他微应用或整个系统iframesingle-spasingle-spa原理基础实现流程应用程序注册:在single-spa中,调用`registerApplication`函数实现,注册需要提供子应用的名称、加载函数、路由规则等信息路由管理:根据当前的路由状态来加载和激活相应的子应用子应用加载:当需要加载某个子应用时,single-spa会调用加载函数来动态加载子应用的代码和资源,加载函数可以是一个异步函数或者返回一个promise,用于异步加载子应用的资源生命周期管理bootstrap(初始化): 在这个阶段,子应用被加载到内存中,但尚未挂载到 DOM 中。这个阶段可以用来初始化子应用,例如加载一些必要的资源或设置一些全局配置。mount(挂载): 在这个阶段,子应用被挂载到 DOM 中,并开始执行其内部的渲染逻辑。这个阶段是子应用真正开始工作的时候,可以在这里执行一些初始化渲染或绑定事件等操作。unmount(卸载): 在这个阶段,子应用被从 DOM 中卸载,并停止执行其内部的渲染逻辑。这个阶段可以用来清理子应用的状态或释放资源,以便在下次挂载时重新初始化。unload(卸载后): 在这个阶段,子应用被完全卸载并从内存中释放。这个阶段是应用程序的生命周期的最后阶段,可以在这里执行一些清理或释放资源的操作。共享状态:single-spa 允许不同的子应用之间共享状态。可以使用一些全局状态管理工具(如 Redux、Vuex 等)来管理应用之间共享的状态,或者使用 single-spa 提供的跨应用程序通信机制来实现状态共享。错误处理:提供了一些机制来处理应用加载过程中的错误,并提供了一些默认的错误处理行为。也可以自定义错误处理逻辑,以便更好地处理各种错误情况JS沙箱沙箱是一种用于隔离 JavaScript 代码的机制,可以在同一个页面中运行多个不同源的 JavaScript 代码,同时确保它们之间不会相互干扰或造成安全漏洞。JavaScript 沙箱通常用于在 Web 应用程序中实现安全的代码执行环境,以防止恶意代码对页面造成破坏或窃取用户信息功能和特点隔离环境: 通过创建一个独立的执行环境来隔离不同的 JavaScript 代码。每个沙箱都拥有自己的全局对象和执行上下文,使得其中的代码无法访问其他沙箱中的变量、函数或对象。安全性: 可以帮助确保页面的安全性,防止恶意代码对页面造成破坏或窃取用户信息。通过限制沙箱中的 JavaScript 代码的权限和访问范围,可以有效地防止一些常见的安全漏洞,如 XSS(跨站脚本攻击)和 CSRF(跨站请求伪造)等。沙箱配置: 通常允许对沙箱进行配置,以满足不同的安全需求和使用场景。例如,可以配置沙箱的运行时环境、访问控制策略、沙箱间通信机制等。资源限制: 可以限制沙箱中 JavaScript 代码的资源使用,包括 CPU、内存、网络等资源。这有助于防止恶意代码占用过多的资源或进行网络攻击。错误隔离: 可以帮助隔离不同 JavaScript 代码的错误,使得其中一个沙箱中的错误不会影响到其他沙箱中的代码执行。这有助于提高页面的稳定性和可靠性。qiankun工作原理应用加载:通过动态创建 script 标签的方式加载子应用的入口文件。加载完成后,会执行子应用暴露出的生命周期函数。生命周期管理:要求每个子应用都需要暴露出 bootstrap、mount 和 unmount 三个生命周期函数。bootstrap 函数在应用加载时被调用,mount 函数在应用启动时被调用,unmount 函数在应用卸载时被调用。沙箱隔离:通过 Proxy 对象创建了一个 JavaScript 沙箱,用于隔离子应用的全局变量,防止子应用之间的全局变量污染。样式隔离:通过动态添加和移除样式标签的方式实现了样式隔离。当子应用启动时,会动态添加子应用的样式标签,当子应用卸载时,会移除子应用的样式标签通信机制:提供了一个全局的通信机制,允许子应用之间进行通信。qiankun如何加载子应用采用动态加载子应用,通过监听主应用的路由变化,根据当前的路由状态来动态加载和卸载子应用,使用import-html-entry库内部采用HTML Entry的方式,通过设置html作为资源入口,加载远程html解析DOM,从而获取js、css等静态资源来实现渲染。当配置子应用的entry之后,qiankun会通过fetch获取到子应用的html字符串,然后通过正则匹配获取html对应的js、css、注释、入口、脚本entry等等template: HTML 模板script:JS 脚本(内联、外联)styles:css 样式表(内联、外联)entry:子应用入口 js 脚本文件使用HTML Entry的优点无需打包成单个 JS bundle: 在使用 HTML Entry 时,子应用程序不需要被打包成单个 JavaScript bundle。这意味着可以继续使用 CSS 提取、资源并行加载和首屏加载优化等技术,而不必担心打包过程带来的复杂性。无需关心子应用的文件名和更新: 使用 HTML Entry,不需要担心子应用程序的 JavaScript 文件名会发生变化,也不需要手动更新打包配置来适应按需加载功能。qiankun 在懒加载 JavaScript 脚本时会自动处理 URL,并且不受文件名变化的影响。自动补全 URL: qiankun 在懒加载 JavaScript 脚本时会基于 entry 配置项自动补全 URL。这意味着不需要为按需加载功能特别修改打包配置,qiankun 会处理相关的 URL 自动补全工作qiankun如何做应用隔离单实例模式下的沙箱隔离(快照沙箱)通过记录和保留每个子应用程序加载前的全局状态(比如 window 对象的内容),然后在子应用程序执行期间,拦截和记录对全局状态的任何修改。当需要卸载某个子应用程序时,快照沙箱会恢复原始的全局状态,以确保其他子应用程序或主应用程序不受影响。实现步骤:记录全局状态: 在加载子应用程序之前,记录当前的全局状态,包括 window 对象的内容以及其他全局变量和对象的状态。创建沙箱环境: 创建一个代理对象(利用es6的proxy)来代替全局对象,例如创建一个代理 window 对象。这个代理对象将用于拦截对全局对象的访问和修改操作。拦截和记录操作: 在代理对象上设置拦截器,用于拦截对全局对象的访问和修改操作。在拦截器中,记录所有的操作,包括属性的读取、写入和删除等。执行子应用程序代码: 将子应用程序的 JavaScript 代码加载到沙箱环境中执行。在代码执行期间,所有对全局对象的操作都会被代理对象拦截和记录。卸载子应用程序: 当需要卸载子应用程序时,恢复原始的全局状态,包括清理代理对象和拦截器。这样可以确保其他子应用程序或主应用程序不受影响。利用 ES6 的 Proxy,我们可以做到以下几点:拦截属性访问: 我们可以在 Proxy 对象上设置 get 拦截器,用于拦截对全局对象属性的读取操作。这样,当子应用尝试访问全局对象的属性时,Proxy 就会拦截并记录下这个操作。拦截属性设置: 我们可以在 Proxy 对象上设置 set 拦截器,用于拦截对全局对象属性的修改操作。这样,当子应用尝试修改全局对象的属性时,Proxy 就会拦截并记录下这个操作。拦截属性删除: 我们可以在 Proxy 对象上设置 deleteProperty 拦截器,用于拦截对全局对象属性的删除操作。这样,当子应用尝试删除全局对象的属性时,Proxy 就会拦截并记录下这个操作。多实例下的沙箱隔离(proxy)代理拦截: qiankun 使用了 ES6 的 Proxy 对象来拦截对全局对象的操作,如 window 对象。这意味着子应用程序的代码不会直接操作真正的 window 对象,而是通过代理对象进行操作。环境隔离: qiankun 在每个子应用程序中创建了一个独立的代理对象和一个副本的 window 对象(称为 fakeWindow)。这样,每个子应用程序都有自己的沙箱环境,与其他子应用程序和主应用程序的环境完全隔离开来。状态管理: 由于沙箱隔离,激活和卸载子应用程序时不需要操作状态池来更新或还原主应用程序和其他子应用程序的环境状态。因为子应用程序的环境状态都是在各自的沙箱环境中维护的,互不干扰。统一 URL 下多个子应用支持: qiankun 的沙箱机制也支持在统一 URL 下加载多个子应用程序的场景。每个子应用程序都有自己的沙箱环境,因此不会相互影响,可以安全地共存于同一页面中。qiankun如何做样式隔离样式隔离主要通过 HTML 结构和动态样式表实现:样式表解析和包裹: 当子应用挂载时,qiankun 会解析所有样式表(包括内联样式和外联样式),并将它们全部包裹在 style 标签中,插入到 HTML 模板中。这样可以确保子应用的样式不会直接影响其他子应用或主应用的样式。样式表的动态切换: 当从一个子应用切换到另一个子应用时,qiankun 会执行子应用的 mounted 生命周期,在此期间,先执行卸载逻辑,将当前子应用的样式表全部删除。然后,在新子应用开始挂载时,再将新子应用的样式表挂载到页面上。这样就可以避免不同子应用的样式同时存在于同一个项目中,实现了样式的基本隔离。qiankun中如何实现父子应用间的通信自定义事件机制: 可以通过自定义事件来进行通信。父项目可以通过 window.dispatchEvent() 方法触发自定义事件,而子项目则可以通过 window.addEventListener() 方法监听相应的事件。这样就可以在父子项目之间传递消息和数据。全局状态管理: 可以共享一个全局状态管理器,例如 Redux、Vuex 等。通过在全局状态管理器中存储共享数据,父子项目可以实现数据的共享和同步,从而实现通信。发布/订阅模式: 可以使用发布/订阅模式来进行通信。父项目可以充当发布者,子项目可以充当订阅者。父项目通过发布消息,而子项目则通过订阅消息来接收数据。全局事件总线: 可以在父项目中创建一个全局事件总线,用于中转消息和数据。父项目和子项目都可以通过全局事件总线来发送和接收消息,从而实现通信。window 对象属性: 父项目和子项目可以通过 window 对象的属性来进行通信。例如,父项目可以将数据存储在 window 对象的属性中,而子项目则可以通过访问相应的属性来获取数据。qiankun中如何实现组件在不同项目间的共享父子项目间的组件共享: 主项目加载时,将需要共享的组件挂载到全局对象(如 window)上,在子项目中直接注册和使用该组件。子项目可以通过全局对象来获取共享组件,并在需要的地方进行使用。子项目间的组件共享(弱依赖): 子项目可以通过主项目提供的全局变量来获取共享组件。如果子项目中的共享组件是异步加载的,可以在加载组件之前先检查全局对象中是否存在该组件,如果存在则直接复用,否则再加载该组件。子项目间的组件共享(强依赖): 在主项目中通过 loadMicroApp 函数手动加载提供组件的子项目,并将需要共享的组件挂载到全局对象上。然后将 loadMicroApp 函数传递给子项目,在子项目中需要使用共享组件的地方,手动加载提供组件的子项目,并等待加载完成后即可获取共享组件。qiankun中应用之间如何复用依赖npm包CDN 引入: 如果依赖库被托管在 CDN 上,可以直接在 HTML 文件中通过