第17期 - 搬新园区

封面图来源于新园区公司楼下的全家便利店,觉得蛮有氛围的。
技术笔记-微前端相关
微前端前置概念
单页应用
传统前端应用一般是 多页应用(MPA - Multi-Page Application),页面切换时会重新加载 HTML、CSS、JS。 SPA 只加载一个 HTML 页面,通过 JavaScript 动态渲染 UI,并使用路由切换不同页面,提升用户体验。微前端通常基于 SPA 实现,但不同团队的 SPA 可能使用不同的框架(如 React、Vue、Angular)
前端模块化 & 组件化
模块化:将代码拆分成独立的模块,提高可维护性(如 ES Modules、CommonJS、AMD)。 组件化:UI 组件封装成独立单元,可复用、组合(如 React 组件、Vue 组件、Web Components)。 微前端可以理解为“应用级别的模块化”,把整个系统拆分成多个可独立部署的前端应用。
微服务架构
微前端借鉴了微服务的思想,将一个大前端应用拆分成多个独立的子应用,每个子应用可以独立开发、部署和运行。 微服务 vs 微前端 微服务:后端拆分成多个小服务(Spring Cloud、Kubernetes)。 微前端:前端拆分成多个独立应用(qiankun、single-spa、module federation)。
WebComponent(Web 组件标准)
WebComponent 是浏览器原生支持的一种 组件封装技术,包括: Custom Elements(自定义 HTML 元素) Shadow DOM(样式隔离) HTML Templates(模板复用) 微前端可以使用 WebComponent 作为子应用封装方式,但兼容性需要考虑
运行时沙盒(JS 隔离机制)
微前端需要保证子应用的 JS 互不影响,沙盒机制主要用于 隔离全局变量: 单例沙盒(如 qiankun):只允许一个子应用运行。 多实例沙盒(如 micro-app):支持多个子应用并存,确保互不影响。 Proxy 代理:利用 ES6 Proxy 代理 window 对象,限制子应用修改全局变量。
资源隔离(CSS 样式隔离)
避免子应用的 CSS 污染全局,微前端一般使用: Shadow DOM:WebComponents 的封装方式,天然隔离。 CSS Modules:本地作用域 CSS,避免全局污染。 动态作用域(如 qiankun 的 Scoped CSS):给 CSS 选择器增加前缀,防止冲突。
主应用 & 子应用(Host & Micro Apps)
主应用(Host):负责微前端的整体布局、路由管理、应用加载。 子应用(Micro Apps):独立运行的前端应用,可以基于不同框架开发,如 Vue、React、Angular。 主应用和子应用的通信方式: 全局变量(window) Event Bus(事件总线) CustomEvent(自定义事件) postMessage(跨窗口通信) 基于 props 传递数据(如 qiankun 的通信机制)
对照表:
概念 | 作用 |
---|---|
SPA | 让前端单页面应用更流畅,不用刷新页面 |
模块化 | 代码拆分,提高可维护性 |
微服务 | 借鉴后端微服务,前端拆分独立应用 |
WebComponent | 组件封装,支持 Shadow DOM 隔离 |
运行时沙盒 | 保护 window,避免子应用污染全局 |
CSS 隔离 | 解决子应用样式冲突问题 |
主/子应用 | 微前端架构中的核心角色 |
基于 Iframe
无特定框架,直接使用 iframe 技术。每个子应用通过 iframe 进行嵌入,子应用之间通过 postMessage 或其他通信方式进行交互。
隔离性强,子应用完全隔离,互不干扰。
不需要修改子应用的代码,直接在父应用中嵌入。
可通过不同域名部署子应用,避免跨域问题
每个子应用都需要加载独立的 iframe,资源加载较慢 父子应用之间的通信需要额外处理,通常通过 postMessage 各个应用完全独立,不能直接共享 JavaScript 和样式等资源。 iframe 会有页面边框,可能影响整体 UI 设计
适用于比较传统的后台管理系统,或者子应用本身是独立系统且不需要频繁交互的情况
基于 Single-spa
Single-spa 是一个将多个单页面应用聚合为一个整体应用的 JavaScript 微前端框架。在同一页面上使用多个前端框架 而不用刷新页面,独立部署每一个单页面应用 文档参考:https://zh-hans.single-spa.js.org/docs/getting-started-overview
使用 single-spa 来管理和加载多个子应用,子应用通过生命周期管理进行加载、卸载等操作。
子应用可以使用不同的前端框架(如 React、Vue、Angular 等),技术栈混合 可以实现良好的路由控制,子应用可以响应父应用的路由变化。
生命周期和路由自主管理:single-spa 提供的生命周期钩子允许子应用根据需要启动和销毁 多应用同时加载可能会影响性能,尤其是复杂的前端框架。 子应用间可能存在一些状态共享或样式污染问题
适用于需要使用多个框架的复杂系统,或一些后台管理系统和大型 Web 应用,尤其是需要处理多个子系统的情况。
基于 qiankun
通过 qiankun 来实现主应用和子应用的管理。子应用通过 JavaScript 沙盒运行,确保全局变量和样式的隔离。通过沙盒机制避免子应用间相互干扰
支持不同技术栈 支持动态加载、路由控制,适合大规模应用 直接集成到已有应用中,不需要修改子应用
初期集成可能较为复杂,需要考虑各个子应用的生命周期和路由配置 有性能损耗,尤其是在处理复杂场景时
适用于大型企业级应用、后台管理系统、SaaS 系统,尤其是当需要在主应用中整合多个子应用,并且希望子应用拥有独立生命周期时。
基于 Web Components
使用原生 Web Components,或结合框架如 Single-spa 或 qiankun 来管理组件
使用原生的 Web Components(如
支持技术栈无关,可以将任何框架的组件封装为 Web Component 强大的封装和样式隔离,避免了子组件的样式污染 可以轻松与现有应用集成,无需重构整个项目。
在某些浏览器上可能需要 polyfill 支持,兼容性问题。 对于复杂的应用,可能会面临性能问题,尤其是多个组件在同一页面中同时渲染时
适用于轻量级的微前端实现,尤其是在组件化的场景下,如某些后台管理系统的独立模块,或者移动端应用的模块化。
总结:使用 Web Components 来实现微前端的方式,主要是将 不同框架的单页应用 或 系统页面 作为独立的组件进行封装,并通过 Web Components 标准来使它们可以在主应用中展示和交互。
基于 Webpack 5 的 Module Federation
Webpack 5 引入了 Module Federation,允许不同应用共享模块和代码。 通过 import() 动态加载远程模块,使得各个子应用可以共享模块或组件
共享代码和组件,避免了重复加载,提升了性能。 更加灵活,支持按需加载,避免应用过度耦合。 适合大型应用和复杂场景,特别是需要跨应用共享代码时
配置复杂,需要在 Webpack 中进行大量配置。 对版本管理要求较高,不同子应用的模块版本可能导致冲突。
适用于大型前端应用,尤其是需要在多个应用之间共享代码的场景,例如跨项目共享公共组件和库。
多个独立的构建可以组成一个应用程序,这些独立的构建之间不应该存在依赖关系,因此可以单独开发和部署它们。区分本地模块和远程模块。本地模块即为普通模块,是当前构建的一部分。远程模块不属于当前构建,并在运行时从所谓的容器加载。每个构建都充当一个容器,也可将其他构建作为容器。通过这种方式,每个构建都能够通过从对应容器中加载模块来访问其他容器暴露出来的模块。 https://webpack.docschina.org/concepts/module-federation/
对照表:
方式 | 框架 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
Iframe | 无 | 隔离性强,简单易用 | 性能差,UI 整合差,通信复杂 | 传统后台管理,子系统完全独立的场景 |
Single-spa | single-spa | 支持多种前端框架,子应用独立运行 | 需要手动管理应用状态和路由 | 适用于单页面应用,支持多个框架的微前端场景 |
Qiankun | qiankun | 基于 single-spa,封装更完整,易用 | 依赖 single-spa,性能优化复杂 | 适用于中后台系统,单页面微前端应用 |
Micro-app | micro-app | 基于 WebComponent,支持 JS 沙盒 | 需要浏览器支持 WebComponent,复杂度较高 | 适用于前端技术栈不统一的微前端项目 |
Module Federation | Webpack 5 | 组件级别共享,避免重复打包,独立部署 | 仅适用于 Webpack 生态,构建配置复杂 | 适用于大型前端项目,渐进式微前端改造 |