新轮子 Mooa:使用 mooa 微服务化 Angular 应用

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介:

Angular 基于 Component 的思想,可以让其在一个页面上同时运行多个 Angular 应用;可以在一个 DOM 节点下,存在多个 Angular 应用,即类似于下面的形式:

 
  1. <app-home _nghost-c3="" ng-version="5.2.8">

  2.  <app-help _nghost-c0="" ng-version="5.2.2" style="display:block;"><div _ngcontent-c0=""></div></app-help>

  3.  <app-app1 _nghost-c0="" ng-version="5.2.3" style="display:none;"><nav _ngcontent-c0="" class="navbar"></div></app-app1>

  4.  <app-app2 _nghost-c0="" ng-version="5.2.2" style="display:none;"><nav _ngcontent-c0="" class="navbar"></div></app-app2>

  5. </app-home>

可这一样一来,难免需要做以下的一些额外的工作:

  • 创建子应用项目模板,以统一 Angular 版本

  • 构建时,删除子应用的依赖

  • 修改第三方模块

而在这其中最麻烦的就是第三方模块冲突问题。思来想去,在三月中旬,我在 Mooa 中添加了一个 iframe 模式。

Mooa

Mooa 是一个为 Angular 服务的微前端框架,它是一个基于 single-spa,针对 IE 10 及 IFRAME 优化的微前端解决方案。

Mooa 框架与 Single-SPA 不一样的是,Mooa 采用的是 Master-Slave 架构,即主-从式设计。

对于 Web 页面来说,它可以同时存在两个到多个的 Angular 应用:其中的一个 Angular 应用作为主工程存在,剩下的则是子应用模块。

  • 主工程,负责加载其它应用,及用户权限管理等核心控制功能。

  • 子应用,负责不同模块的具体业务代码。

在这种模式下,则由主工程来控制整个系统的行为,子应用则做出一些对应的响应。

iframe 微服务架构设计

在这里,总的设计思想和之前的《如何解构单体前端应用——前端应用的微服务式拆分》中介绍是一致的:

ae1e0e705b908527d53c757b5ee9b04f554261b2

Mooa 架构

主要过程如下:

  • 主工程在运行的时候,会去服务器获取最新的应用配置。

  • 主工程在获取到配置后,将一一创建应用,并为应用绑定生命周期。

  • 当主工程监测到路由变化的时候,将寻找是否有对应的路由匹配到应用。

  • 当匹配对对应应用时,则创建或显示相应应用的 iframe,并隐藏其它子应用的 iframe。

其加载形式与之前的 Component 模式并没有太大的区别:

776254d4a19b703a5be97491ef9531d9f0e17ca2

Mooa Component 加载

而为了控制不同的 iframe 需要做到这么几件事:

  1. 为不同的子应用分配 ID

  2. 在子应用中进行 hook,以通知主应用:子应用已加载

  3. 在子应用中创建对应的事件监听,来响应主应用的 URL 变化事件

  4. 在主应用中监听子程序的路由跳转等需求

因为大部分的代码可以与之前的 Mooa 复用,于是我便在 Mooa 中实现了相应的功能。

微前端框架 Mooa 的特制 iframe 模式

iframe 可以创建一个全新的独立的宿主环境,这意味着我们的 Angular 应用之间可以相互独立运行,我们唯一要做的是:建立一个通讯机制

它可以不修改子应用代码的情况下,可以直接使用。与此同时,它在一般的 iframe 模式进行了优化。使用普通的 iframe 模式,意味着:我们需要加载大量的重复组件,即使经过 Tree-Shaking 优化,它也将带来大量的重复内容。如果子应用过多,那么它在初始化应用的时候,体验可能就没有那么友好。但是与此相比,在初始化应用的时候,加载所有的依赖在主程序上,也不是一种很友好的体验。

于是,我就在想能不能创建一个更友好地 IFrame 模式,在里面对应用及依赖进行处理。如下,就是最后生成的页面的 iframe 代码:

 
  1. <app-home _nghost-c2="" ng-version="5.2.8">

  2.  <iframe frameborder="" width="100%" height="100%" src="http://localhost:4200/assets/iframe.html" id="help_206547" style="display:block;"></iframe>

  3.  <iframe frameborder="" width="100%" height="100%" src="http://localhost:4200/assets/iframe.html" id="app_235458 style="display:none;"></iframe>

  4. </app-home>

对,两个 iframe 的 src 是一样的,但是它表现出来的确实是两个不同的 iframe 应用。那个 iframe.html 里面其实是没有内容的:

 
  1. <!doctype html>

  2. <html lang="en">

  3. <head>

  4.  <meta charset="utf-8">

  5.  <title>App1</title>

  6.  <base href="/">

  7.  <meta name="viewport" content="width=device-width,initial-scale=1">

  8.  <link rel="icon" type="image/x-icon" href="favicon.ico">

  9. </head>

  10. <body>

  11. </body>

  12. </html>

(PS:详细的代码可以见 https://github.com/phodal/mooa)

只是为了创建 iframe 的需要而存在的,对于一个 Angular 应用来说,是不是一个 iframe 的区别并不大。但是,对于我们而言,区别就大了。我们可以使用自己的方式来控制这个 IFrame,以及我们所要加载的内容。如:

  • 共同 Style Guide 中的 CSS 样式。如,在使用 iframe 集成时,移除不需要的

  • 去除不需要重复加载的 JavaScript。如,打包时不需要的 zone.min.js、polyfill.js 等等

注意:对于一些共用 UI 组件而言,仍然需要重复加载。这也就是 iframe 模式下的问题。

微前端框架 Mooa iframe 通讯机制

为了在主工程与子工程通讯,我们需要做到这么一些事件策略:

发布主应用事件

由于,我们使用 Mooa 来控制 iframe 加载。这就意味着我们可以通过 document.getElementById 来获取到 iframe,随后通过 iframeEl.contentWindow 来发布事件,如下:

 
  1. let iframeEl: any = document.getElementById(iframeId)

  2. if (iframeEl && iframeEl.contentWindow) {

  3.  iframeEl.contentWindow.mooa.option = window.mooa.option

  4.  iframeEl.contentWindow.dispatchEvent(

  5.  new CustomEvent(MOOA_EVENT.ROUTING_CHANGE, { detail: eventArgs })

  6.  )

  7. }

这样,子应用就不需要修改代码,就可以直接接收对应的事件响应。

监听子应用事件

由于,我们也希望能直接在主工程中处理子程序的事件,并且不修改原有的代码。因此,我们也使用同样的方式来在子应用中监听主应用的事件:

 
  1. iframeEl.contentWindow.addEventListener(MOOA_EVENT.ROUTING_NAVIGATE, function(event: CustomEvent) {

  2.  if (event.detail) {

  3.  navigateAppByName(event.detail)

  4.  }

  5. })

示例

同样的我们仍以 Mooa 框架作为示例,我们只需要在创建 mooa 实例时,配置使用 iframe 模式即可:

 
  1. this.mooa = new Mooa({

  2.  mode: 'iframe',

  3.  debug: false,

  4.  parentElement: 'app-home',

  5.  urlPrefix: 'app',

  6.  switchMode: 'coexist',

  7.  preload: true,

  8.  includeZone: true

  9. });

  10. ...

  11. that.mooa.registerApplicationByLink('help', '/assets/help', mooaRouter.matchRoute('help'));

  12. that.mooa.registerApplicationByLink('app1', '/assets/app1', mooaRouter.matchRoute('app1'));

  13. this.mooa.start();

  14. ...

  15. this.router.events.subscribe((event: any) => {

  16.  if (event instanceof NavigationEnd) {

  17.  that.mooa.reRouter(event);

  18.  }

  19. });

子程序则直接使用:https://github.com/phodal/mooa-boilerplate 就可以了。

98900183430e863c672c2ce828f5c083ddece29a

GitHub 地址:https://github.com/phodal/mooa


原文发布时间:2018年04月18日

作者:phodal_

本文来源:CSDN  如需转载请联系原作者

目录
相关文章
|
27天前
|
运维 监控 测试技术
深入理解微服务架构及其在现代应用开发中的应用
【10月更文挑战第6天】深入理解微服务架构及其在现代应用开发中的应用
101 1
|
27天前
|
监控 API 开发者
深入理解微服务架构:构建可扩展的应用程序
【10月更文挑战第6天】深入理解微服务架构:构建可扩展的应用程序
43 0
|
6天前
|
运维 持续交付 开发工具
深入浅出:GitOps在微服务架构中的应用
【10月更文挑战第26天】本文深入探讨了GitOps在微服务架构中的应用,介绍了其核心理念、自动化部署流程和增强的可观测性。通过实例展示了GitOps如何简化服务部署、配置管理和故障恢复,并推荐了一些实用工具和开发技巧。
|
26天前
|
消息中间件 监控 API
理解微服务架构:构建灵活和可扩展的应用
【10月更文挑战第7天】理解微服务架构:构建灵活和可扩展的应用
|
26天前
|
消息中间件 监控 API
深入理解微服务架构:构建可扩展与灵活的应用
【10月更文挑战第7天】深入理解微服务架构:构建可扩展与灵活的应用
39 0
|
4天前
|
JavaScript 持续交付 Docker
解锁新技能:Docker容器化部署在微服务架构中的应用
【10月更文挑战第29天】在数字化转型中,微服务架构因灵活性和可扩展性成为企业首选。Docker容器化技术为微服务的部署和管理带来革命性变化。本文探讨Docker在微服务架构中的应用,包括隔离性、可移植性、扩展性、版本控制等方面,并提供代码示例。
29 1
|
16天前
|
缓存 监控 JavaScript
Angular 应用打包和部署
【10月更文挑战第16天】Angular 应用的打包和部署是一个综合性的过程,需要考虑多个方面的因素。通过合理的打包和部署策略,可以确保应用在生产环境中稳定运行,并为用户提供良好的体验。你需要根据实际情况选择合适的部署方式,并不断优化和改进部署流程,以适应业务的发展和变化。
|
18天前
|
Cloud Native Go API
Go语言在微服务架构中的创新应用与实践
本文深入探讨了Go语言在构建高效、可扩展的微服务架构中的应用。Go语言以其轻量级协程(goroutine)和强大的并发处理能力,成为微服务开发的首选语言之一。通过实际案例分析,本文展示了如何利用Go语言的特性优化微服务的设计与实现,提高系统的响应速度和稳定性。文章还讨论了Go语言在微服务生态中的角色,以及面临的挑战和未来发展趋势。
|
19天前
|
运维 Go 开发者
Go语言在微服务架构中的应用与优势
本文深入探讨了Go语言在构建微服务架构中的独特优势和实际应用。通过分析Go语言的核心特性,如简洁的语法、高效的并发处理能力以及强大的标准库支持,我们揭示了为何Go成为开发高性能微服务的首选语言。文章还详细介绍了Go语言在微服务架构中的几个关键应用场景,包括服务间通信、容器化部署和自动化运维等,旨在为读者提供实用的技术指导和启发。
|
22天前
|
负载均衡 Go API
探索Go语言在微服务架构中的应用与优势
在这篇技术性文章中,我们将深入探讨Go语言(又称为Golang)在构建微服务架构时的独特优势。文章将通过对比分析Go语言与其他主流编程语言,展示Go在并发处理、性能优化、以及开发效率上的优势。同时,我们将通过一个实际的微服务案例,详细说明如何利用Go语言构建高效、可扩展的微服务系统。