引言
微前端是微服务概念在前端的应用。在微前端架构下,一个大型单一的前端应用被拆分成多个小型、独立的子应用,这些子应用可以独立开发、独立部署、独立运行,从而带来更加灵活高效的项目开发和管理。
作为现代前端开发的趋势,许多企业的技术栈融入了微前端,有些是选择成熟的框架如 Qiankun、Micro-App 或 Single-SPA,有些是自研解决方案。
微前端最简单的实现形式是基于Iframe。本文主要从一个简单的微前端案例入手,通过这个简单的Demo,让我们对微前端框架及其设计理念有个初步的理解。
Demo源代码讲解
目录结构
1 | iframe-demo |
这个Demo的目录结构非常简单,主要分为三部分:
- 两个子应用cart、catalog
- 全局事件总线
- 主应用
可以看到这个简单的项目已经体现了微前端的核心设计:应用管理、隔离和共享。
应用管理
从composition.html
文件我们可以看出这个项目的应用管理非常简单,两个子应用通过iframe
标签加载,共同存在于同一个页面。
1 | <link rel="stylesheet" href="style.css" /> |
隔离
由于使用的是iframe标签,两个子应用天然地存在CSS和JS隔离,不会有样式和运行时的冲突。
微前端 why iframe not div?
为什么微前端使用iframe
做隔离,而不是普通div
。
主要是因为iframe
在浏览器中具有天然的隔离环境,主要表现在:
- JavaScript 隔离:
iframe
内的 JavaScript 运行在独立的全局上下文中。这意味着,iframe
内的 JavaScript 变量和函数不会影响到主页面,反之亦然。这种特性对于确保应用间不会相互干扰是非常重要的。 - 样式隔离:
iframe
内的样式不会影响到外部页面。每个iframe
有自己的文档流,所以里面的 CSS 只会作用于iframe
内部,不会泄露到外部,这保证了样式的独立性和一致性。 - DOM 隔离:每个
iframe
都有自己的 DOM 树,与主页面的 DOM 树完全隔离。这意味着,iframe 内的 DOM 操作不会影响到外部页面,减少了应用间的直接 DOM 冲突。
这些隔离特性对于普通的div
标签是没有的。
共享(通信)
虽然iframe
能实现简单的微前端架构,但是通过代码中设计的全局事件总线(EventBus.js
文件),我们可以看出基于iframe
的微前端需要单独设计跨域通信方式。
本案例主要是通过PostMessage
方法实现的。PostMessage
是一种安全地实现不同浏览器窗口(包括弹出窗口和iframe
)间通信的方式。允许不同源(origin
)的窗口进行数据交换,从而克服了同源策略的限制。适用于多种场景,如页面与弹出窗口、页面与嵌入的iframe
、甚至是不同的web workers之间的通信。
基本用法
包括两部分:发送消息和接收消息。
发送消息: window.postMessage
这个方法接受两个参数:要发送的消息和消息接收方的源(origin
)。但出于安全考虑,这通常不推荐。
1 | otherWindow.postMessage(message, targetOrigin); // otherWindow 是另一个窗口的引用,例如一个 iframe 或者通过 window.open 打开的窗口 |
message
:你想要发送的数据。targetOrigin
:指定目标窗口的源,例如 “https://example.com
“。这是一种安全机制,用来确保消息只被预期的接收者接收。如果你不关心目标窗口的源,也可以使用 “*” 作为通配符。
**接收消息:**在目标窗口添加一个事件监听器来监听 message
事件
1 | window.addEventListener("message", (event) => { |
在本项目中,composition
主应用的JS
脚本中注册了message
事件监听,将基座应用接收到的消息转发给所有子应用。
1 | const sendReceivedMessageToAllIframes = (event) => { |
在catalog
子应用中,注册了一个全局事件总线,并且给按钮注册了点击事件,当按钮点击后,会触发productToCart
事件,在该事件中,会向主应用发送消息。
最终该消息会经过主应用,接着由cart
子应用中的全局事件总线接收,执行add
方法。
大致的交互示意图如下所示:
总结
一个 iframe
具备四层能力:文档的加载能力、HTML 的渲染能力、独立执行 JavaScript 的能力、隔离样式的能力。这些能力,其实也是微前端项目设计的核心要求。通过学习本项目,我们可以很好地初步学习微前端,为后来深入学习Single-SPA、qiankun等框架提供理论基础。