微前端迁移、本地开发与测试指南
1. 从单体应用到微前端的迁移策略
从单体应用向微前端过渡并没有通用的方法,这取决于现有的系统以及新架构想要达成的目标。利用前端集成技术,逐步用新的微前端应用替换旧的单体应用,是一种值得考虑的有效策略。
2. 本地开发的挑战与应对
在单体应用开发中,本地开发相对简单,只需检出一个包含完整应用启动所需代码的仓库,就能在本地运行并测试整个应用。但在微前端这种分布式架构下,情况变得复杂起来。
2.1 避免运行其他团队的代码
每个团队都有自己的代码仓库,且可能使用不同的技术栈。虽然开发者可以同时检出自己团队和其他团队的代码仓库,但这很快会变得繁琐。了解其他团队的开发环境会带来额外的麻烦,而且当其他团队的代码出现问题导致应用无法启动时,会影响自己的开发工作。因此,开发者应专注于自己团队的代码。
对于单仓库(monorepo)的概念,它将独立应用或库的代码放在一个版本控制仓库中,便于一次性下载和更新多个项目,并管理共享依赖。如果将微前端仅视为一个团队对前端进行模块化的集成技术集合,单仓库方法是合理的。但如果想利用多个独立团队无需紧密协调就能并行工作的组织优势,单仓库则是一种反模式。团队的应用应该保持独立,不共享代码或部署管道,独立的仓库可以避免不必要的团队间依赖。
2.2 模拟片段(Mocking Fragments)
如果不能运行其他团队的代码,如何进行开发呢?在页面层面,解决方案是用模拟版本替换其他团队的片段。以 Team Decide 的产品页面为例:
1. 进入示例代码目录,运行命令:
npm run 21_local_development
。
2. 打开
http://localhost:3001/product/porsche
,可以看到本地开发模式下的产品页面。此时,其他团队的片段(推荐、购买按钮和迷你购物车)已被简单的模拟微前端替换,但页面本身仍能正常工作,例如可以切换白金选项,产品图片会相应更新。
在开发模式下,Team Decide 省略了其他团队片段定义中的脚本和样式标签,不加载这些文件会导致片段位置出现空白块。为了改善这种情况,Team Decide 为三个片段创建了简单的模拟实现,相关代码可在
team-decide/static/mock-fragments.(css|js)
中找到。由于使用自定义元素(Custom Elements)进行集成,模拟片段相对容易。以下是一个模拟代码示例:
class CheckoutMinicart extends HTMLElement {
connectedCallback() {
this.innerHTML = `<div>minicart dummy</div>`;
}
}
window.customElements.define("checkout-minicart", CheckoutMinicart);
这个代码只是简单显示一段文本,如果期望片段抛出事件,可以添加更复杂的功能,例如添加一个触发事件的按钮。
使用模拟片段代替引入真实组件会使开发更简单、更健壮。只需启动自己的应用,如果出现问题,可以确定是自己代码的问题。每个提供片段的团队都应该记录其接口,列出它能理解的参数和可以发出的事件,片段文档可作为创建本地模拟的基础。
需要注意的是,如果在开发和测试软件时需要构建大量复杂的模拟,可能团队边界存在问题,要确保一个用例的责任不会分散在不同团队之间。
2.3 独立开发片段
为了了解片段的开发过程,可以保持示例应用运行,在浏览器中打开
http://localhost:3003/sandbox
查看 Team Checkout 的沙盒页面,该页面展示了他们的两个片段。Team Inspire 也有类似的页面在端口 3002 运行。
沙盒页面作为片段的开发环境,是一个空页面(在这个例子中是有条纹背景的页面),包含团队的片段。页面本身还包括基本的全局样式,如根字体定义和一些 CSS 重置,因为不希望每个片段都重新定义这些样式。像 Podium 这样的工具可以直接创建这样的页面,当然,从头构建也不复杂。还可以使用喜欢的实时重新加载或热代码替换解决方案,让开发更愉快。
在这个环境中,可以测试微前端之间的通信。页面顶部的 “sandbox toggles” 部分包含了一系列片段可以响应的操作。例如,使用 “change sku” 控件可以从一种拖拉机切换到另一种,更改选项会切换购买按钮片段的相关 SKU 属性,其价格也会相应更新。迷你购物车在有人点击购买按钮时也会更新,点击按钮后,产品会出现在迷你购物车中,迷你购物车监听窗口上的
checkout:item_added
事件,就像在完全集成的页面上一样,沙盒页面还有一个专门的添加随机产品按钮来触发该事件。
使用模拟可以带来很大的独立性,减少团队间的摩擦。当测试失败时,可以确定是自己代码的问题,因为不包含其他团队的脚本。这种方法能让集成管道可靠运行,投入一些精力构建好的模拟会让开发更轻松,节省大量时间。
以下是本地开发的流程总结:
|步骤|操作|
| ---- | ---- |
|1|避免运行其他团队代码,专注自身团队代码|
|2|用模拟片段替换其他团队片段进行本地开发|
|3|在沙盒页面独立开发和测试片段|
mermaid 流程图如下:
graph LR
A[本地开发] --> B[避免运行其他团队代码]
A --> C[使用模拟片段]
A --> D[沙盒页面开发片段]
B --> E[专注自身团队代码]
C --> F[替换其他团队片段]
D --> G[测试微前端通信]
2.4 从预发布或生产环境拉取其他团队的微前端
在某些情况下,模拟可能不够用。如果要重现一个神秘的 bug,可能需要使用真实代码进行测试。
对于客户端渲染,这相对容易。无需从头检出和构建其他团队的代码,只需将相关的脚本和样式标签指向预发布或生产环境,从那里获取其他团队片段的代码,就可以调试本地代码与其他团队已发布代码的交互。
Single - spa 更进一步,它有一个名为 single - spa - inspector 的工具,允许从另一个方向进行操作。可以在浏览器中打开生产页面,通过该检查器将已发布的代码版本替换为本地开发代码,Single - spa 使用导入映射(import - maps)来实现这一功能。
对于服务器端渲染,也可以从远程服务器拉取片段。可以让 HTML 组装机制直接从生产环境获取某些路由的标记。如果使用 Nginx 和 SSI,可以通过将其他团队的上游配置更改为生产服务器,同时保持自己的上游指向本地主机来实现。
3. 微前端项目的测试
自动化测试已成为现代软件开发的核心,良好的测试覆盖率可以减少手动测试的需求,并支持持续交付等技术。在微前端项目中,测试与单体项目的测试有相似之处,每个团队都会在不同层面测试其应用,包括快速运行的单元测试和服务测试,以及一些基于浏览器的端到端测试。
3.1 测试金字塔
测试金字塔描述了不同集成级别的测试特点。低集成级别的测试(如单元测试)编写成本低且运行速度快,而高集成级别的测试运行缓慢且维护成本高。在微前端项目中,可以将最顶层的类别(UI 或端到端测试)分为两部分:
1.
隔离测试(大多数测试)
:团队应在没有其他团队代码的隔离环境中进行大部分用户界面测试。这些测试将针对带有模拟片段的软件版本运行,团队自己的片段在隔离环境(沙盒)中进行测试,如前面所述。
2.
完全集成测试(极少数测试)
:即使每个团队都准确测试了其片段和页面,在用户界面边界处仍可能出现错误。因此,应该对关键过渡点进行完全集成测试。
完全集成测试编写困难,因为需要了解至少两个团队的标记结构。引入一个针对整个软件运行的全面集成测试套件效果不佳,尝试往往会导致脆弱的解决方案和大量误报。而且,如果不想引入一个横向测试团队,“谁负责全面集成测试” 这个问题很难回答。
因此,采用分布式方法更好。每个团队可以决定跨其直接相邻团队的边界进行测试。例如,Team Checkout 可以测试其购买按钮微前端在集成到 Team Decide 的产品页面时是否正常工作,Team Decide 可以检查 Team Inspire 的推荐片段是否不为空。
以下是微前端测试的类型总结:
|测试类型|特点|占比|
| ---- | ---- | ---- |
|隔离测试|在无其他团队代码的隔离环境进行,针对带模拟片段的软件版本|大多数|
|完全集成测试|测试关键过渡点,需了解至少两个团队标记结构|极少数|
mermaid 流程图如下:
graph LR
A[微前端测试] --> B[隔离测试]
A --> C[完全集成测试]
B --> D[在隔离环境运行]
B --> E[针对模拟片段软件版本]
C --> F[测试关键过渡点]
C --> G[了解多团队标记结构]
总结
- 可以使用微前端的用户界面集成技术在现有项目中试验这种架构,这些技术还支持逐步迁移,新的微前端可以逐片替换旧的单体用户界面。
- 逐片替换现有系统风险较低,因为始终有一个可用的应用程序。但将新前端与单体前端混合可能会因样式泄漏而具有挑战性,为新微前端使用 Shadow DOM 可以提供帮助。
- 如果与单体用户界面混合不起作用,前端优先或全新项目方法是不错的选择,但风险较高。
- 在本地开发和测试环境中禁用其他团队的代码是个好主意,消除外部代码可以降低复杂性,使环境更稳定。创建简单的模拟微前端有助于获得更真实的布局印象。
- 模拟微前端可以是静态占位符,也可以包含简单功能,如发出事件。
- 可以在专用的沙盒页面上开发片段,该页面以隔离方式显示片段,还可以包含一些自定义用户界面来测试通信(触发事件)或模拟环境变化(如更改 SKU)。
- 几乎所有测试都应针对自己团队的代码进行,尽可能在隔离环境中测试。在某些情况下,可能需要跨团队边界进行测试,可以由中央测试团队负责,或者团队自己测试与相邻团队的集成点。
超级会员免费看
1275

被折叠的 条评论
为什么被折叠?



