首页 > 编程知识 正文

react前端微服务最火的框架,微前端架构

时间:2023-05-05 11:16:19 阅读:8938 作者:3083

基本信息为了解决整个后端服务带来的更改和扩展限制,出现了微服务体系结构(Microservices )。

微服务是一种面向服务体系结构(SOA )的变体,将APP应用程序设计为松散耦合的细粒度服务,并以轻量级通信协议进行组织

具体而言,将APP应用构建为一组小服务。 这些服务可以分别独立部署和独立扩展。 每个服务都有强大的模块边界,可以使用不同的编程语言创建不同的服务,也可以由不同的团队管理

但是,越来越重的前端工程也面临同样的问题,自然考虑将微服务思想应用于前端,产生了“微前端”的概念。

也就是说,这是一种体系结构样式,它由多个独立交付的前端APP应用程序组成。 具体来说,它将前端APP应用程序分解为更小、更容易独立开发、测试和部署的小块,但在用户看来,它仍然是一个单一的聚合产品。

简单来说,就是把每一个巨无霸的前端工序分成一个个的小工序(主要是托福业务)

代码放在github上

特点1 .相对于整个前端库,简单松散的代码库在微前端体系结构中的代码库更易于开发/更小。 一个大型的Tob APP,如果有几百个页面、几百个界面和几百个组件,那么编译起来就是一场灾难。 这个时间意味着什么? 那不仅会延缓我们开发者的时间,还会影响整个团队的效率。 在线时,在Docker、CI等环境中,时间会变长。 如果部署后出现了几个错误,在线上马上修复的话,不知道要忍耐到几点。

使用微前端改造,编译时间短,且功能相对独立。 测试调试程序的时间也变少,容易定位。

2 .优雅的处理历史项目在开发过程中始终不是一个很棒的代码。 通常,我们看到这个,脑子里有两个字((重构) )。

历史工程,祖传的代码配送的压力,当时就在附近熟悉。 当时,想要寻求稳定而彻底重构这些代码,最大的问题是来不及大胆地一步一步地迈出。 在逐步重构的同时,既要保证中间版本的平稳过渡,又要不断提供新的特性。 此时,以微前端方式,独立运行这些项目。 然后找到时间,单独重建这个模块。 可以顺利过渡。

3 .个性化配置打包独立配置的能力在微前端系统中很重要,可以缩小变更范围,降低相关风险

因此,每个微前端都需要自己的连续交付管道,包括在生产环境中构建、测试和部署,并且必须能够独立部署,而无需过多考虑其他代码库或交付管道的当前状态。

使用微前置方式,可以为每个独立的模块创建单独的git库。 这样,即使另一个模块有问题,也不会影响当前发布的模块。

如何构建微前端

加载器Systemjs是可配置的模块加载器,为浏览器和NodeJs启用动态Es模板加载器。 所有标准URL都可以作为模块加载。

script src=' system.js '/script script//针对当前地址的urlsystemjs.import ('./local-module.js ' ); //绝对url的地址systemjs.import (https://code.jquery.com/jquery.js ); /script可以加载任何类型的模块格式,并且由SystemJS自动检测。

包装器single-spa是用于前端微服务化的JavaScript前端解决方案。

特点:

【与各种技术堆栈的兼容性】在同一页面内使用多个技术框架(React、Vue、AngularJS、Angular、Ember等任意技术框架),不需要更新页面。 使用新的技术框架编写代码(不需要重构现有代码),不需要重构现有项目中的代码。 )提高性能)不浪费可以为每个独立模块重建代码的额外资源。 每个独立模块独立工作。 导入映射的实现是单spa的核心部分,首先需要知道什么是导入映射。

让我们先看看两个代码

导入从' moment '; import ' http://moment js.com/downloads/moment.js '; 这是典型的es6 es module代码,但当前不支持浏览器。 为了支持浏览器,需要进行兼容的处理。

我在一个文件里写了上述代码。 很明显第一行不能正常工作。 第2行正常动作。 但是,如果想确保第一行正常工作,就会出现导入映射。 只需在html文件中写如下。

脚本类型=' import map ' { ' imports ' : { ' moment ' : ' https://moment js.com/downloads/moment.js ',}/sc cecece

但是,目前不支持浏览器。 如果要支持,则必须部署system.js。

脚本类型=' sys

temjs-importmap"> { "imports": { "moment": "https://momentjs.com/downloads/moment.js", } }</script><script src="https://cdn.jsdelivr.net/npm/systemjs/dist/system.js"></script>

而在 single-spa 的使用过程中,我们需要用 import-map 在根项目中引入所有的模块文件和子项目,从而在其余项目中可以进行模块的引用,就像上面说的那样,可以把 moment 想象成一个子项目。

<script type="systemjs-importmap"> { "imports": { "module": "https://[cdn-link].js", } }</script><script src="https://cdn.jsdelivr.net/npm/systemjs/dist/system.js"></script> 消息总线

应用微服务化之后,每一个单独的模块都是一个黑盒子, 里面发生了什么,状态改变了什么,外面的模块是无从得知的. 比如模块A想要根据模块B的某一个内部状态进行下一步行为的时候,黑盒子之间没有办法通信.这是一个大麻烦.

每一个模块之间都是有生命周期的.当模块被卸载的时候,如何才能保持后续的正常的通信?

icestarck v1.2.0 推出了正式的官方跨应用通信方案 @ice/stark-data。核心只有两个 API:store(全局变量管理中心) 和 event(全局事件管理中心)。我们针对全局变量,增加了对应的监听事件,基本能覆盖 95% 以上的实际通信场景。简单通过几个场景说明具体使用方式。

import { store } from '@ice/stark-data';// 子应用A设置信息store.set('from', 'A');store.set('current', 0);// 子应用B读取信息const from = store.get('from');const current = store.get('current'); 子应用页面切换参数流转 import { store } from '@ice/stark-data';// 子应用A设置信息store.set('from', 'A');store.set('current', 0);// 子应用B读取信息const from = store.get('from');const current = store.get('current'); 框架应用顶部有 ”消息“ 展示入口,子应用内有阅读消息的能力,阅读完消息后需要通知框架应用刷新“消息”展示信息 // 框架应用import { event } from '@ice/stark-data';function fresh(needFresh) { if (!needFresh) return; fetch('/api/fresh/message').then(res => { // ... });}event.on('freshMessage', fresh);// 子应用import { event } from '@ice/stark-data';event.emit('freshMessage', false);// ...event.emit('freshMessage', true); 构建部署

每个子项目单独打包上传到主项目同级目录。

用户访问主项目index.html后,js加载器会加载apps.config.js。

无论路由是什么,每次必会首先加载主项目,再根据路由来匹配要加载哪个子项目。

在资源服务器上起一个监听服务(我使用的是nodejs脚本+pm2守护),原有子项目的部署方式完全不变(前后端完全分离,资源带hash),当监听服务检测到文件改动时,去子项目部署文件夹里找它的app.js,写入apps.config.js。

讨论

router和vuex是可以选择不暴露的,尤其是vuex,我觉得增加了太多成本,也大大降低了未来同一架构接入其他技术栈的可能性(比如react)

数据管理还是由子项目自行处理的,耦合到主项目上不便于后续的拓展。vuex每个子项目有它自己的store实例。

如果有react/ng等其他技术栈,需要给他们找合适的包装器(single-spa-react (我用的包装器就是single-spa-vue)),理论上是可行的,整套架构除了包装器以外都不用动。

权限 是子系统自己单独管理的,逻辑放在子系统公共组件包里

why not iframe url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。UI 不同步,DOM 结构不共享。想象一下屏幕右下角 1/4 的 iframe 里来一个带遮罩层的弹框,同时我们要求这个弹框要浏览器居中显示,还要浏览器 resize 时自动居中…全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的子应用中实现免登效果。慢。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。

其中有的问题比较好解决(问题1),有的问题我们可以睁一只眼闭一只眼(问题4),但有的问题我们则很难解决(问题3)甚至无法解决(问题2),而这些无法解决的问题恰恰又会给产品带来非常严重的体验问题, 最终导致我们舍弃了 iframe 方案。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。