likes
comments
collection
share

一文了解,关于微前端那些事儿

作者站长头像
站长
· 阅读数 13

背景

随着春夏秋冬的四季更替,宇宙万物的生命轮转,看着日渐庞大的项目代码,面对全新的客户需求,你的心有没有蠢蠢欲动,发出声声呐喊:“我想使用新的技术~”。面对日渐变慢的构建速度,看着肆意浪费的时间滴滴答答走过,你的内心有没有急不可耐。面对项目整合,老板一个眼神的诉说:“把A项目(angular编写)和B项目(react编写)整合到一起吧~” 你有没有心中默默落泪:“这XX是个什么样的工作量~~”

相信很多小伙伴在工作中多多少少都有过类似的场景,那有没有什么神仙办法能够快速解决这些问题呢?看我的眼神 👀 今天介绍的嘉宾将完美解决您上述的所有问题,让我们举双爪欢迎:微前端同学

本篇将为您介绍微前端究竟是什么以及目前常见的微前端实现方案。

微前端概述

Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. -- Micro Frontends

什么是微前端

微前端是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立运行、独立开发、独立部署。微前端架构与框架无关,每个微应用都可以使用不同的框架。 

一文了解,关于微前端那些事儿

微前端的价值

1. 项目增量迁移

迁移是一项非常耗时且艰难的任务,比如有一个管理系统使用 AngularJS 开发维护已经有几年时间,但是随时间的推移和团队成员的变更,无论从开发成本还是用人需求上,AngularJS 已经不能满足要求,于是团队想要更新技术栈,想在其他框架中实现新的需求,但是现有项目怎么办?直接迁移是不可能的,在新的框架中完全重写也不太现实。

使用微前端架构就可以解决问题,在保留原有项目的同时,可以完全使用新的框架开发新的需求,然后再使用微前端架构将旧的项目和新的项目进行整合。这样既可以使产品得到更好的用户体验,也可以使团队成员在技术上得到进步,产品开发成本也降到的最低。

2. 技术选型灵活

使用微前端架构,主框架不限制接入应用的技术栈,微应用具备完全自主权

3. 更快且独立的发布

在目前的单页应用架构中,使用组件构建用户界面,应用中的每个组件或功能开发完成或者bug修复完成后,每次都需要对整个产品重新进行构建和发布,任务耗时操作上也比较繁琐。

在使用了微前端架构后,可以将不能的功能模块拆分成独立的应用,此时功能模块就可以单独构建单独发布了,构建时间也会变得非常快,应用发布后不需要更改其他内容应用就会自动更新,这意味着你可以进行频繁的构建发布操作了。

4. 允许单个团队做出技术决策

因为微前端构架与框架无关,当一个应用由多个团队进行开发时,每个团队都可以使用自己擅长的技术栈进行开发,也就是它允许适当的让团队决策使用哪种技术,从而使团队协作变得不再僵硬。

微前端使用场景

1.拆分巨型应用,使应用变得更加可维护

2.兼容历史应用,实现增量开发

微前端如何实现

1. 多个微应用如何进行组合 ?

在微前端架构中,除了存在多个微应用以外,还存在一个容器应用,每个微应用都需要被注册到容器应用中。 微前端中的每个应用在浏览器中都是一个独立的 JavaScript 模块,通过模块化的方式被容器应用启动和运行。 使用模块化的方式运行应用可以防止不同的微应用在同时运行时发生冲突。

2. 在微应用中如何实现路由 ?

在微前端架构中,当路由发生变化时,容器应用首先会拦截路由的变化,根据路由匹配微前端应用,当匹配到微应用以后,再启动微应用路由,匹配具体的页面组件。

3. 微应用与微应用之间如何实现状态共享 ?

在微应用中可以通过发布订阅模式实现状态共享,比如使用 RxJS。

4. 微应用与微应用之间如何实现框架和库的共享?

可以通过 import-map 和 webpack 中的 externals 属性。

在微应用架构中我们要使用模块化的方式去加载应用。 在最新的模块化当中新增了 import-map 特性,允许我们加载网络模块,而不是一定要将模块下载到本地,我们只需要配置好模块名字和对应的模块地址即可,这样每个微应用在引用公共模块时都可以引用提前配置好的公共模块了。

我们还需要修改微应用本身的 webpack 配置,通过 webpack 的 externals 属性告诉 webpack 在打包应用时哪些模块是不需要被打包的。

常见的微前端解决方案对比

使用 HTTP 服务器(Nginx)的路由来重定向多个微应用

可以理解为把一个大型项目拆分成多个微模板应用,每个微模板应用就代表一个前端服务,然后通过 Nginx 配置代理映射到不同的子模板应用上,这也叫路由分发式微前端,是一个非常古老且传统的方法; 这种方式看上去更像是多个前端应用的聚合,即我们只是将这些不同的前端应用拼凑到一起,使他们看起来像是一个完整的整体。但是它们并不是,每次用户从 A 应用到 B 应用的时候,往往需要刷新一下页面。

优点: 简单、快速、易配置

缺点: 在切换应用时会触发浏览器刷新,影响体验

使用 iframe 及自定义消息传递机制

就其性质而言,iframe 可以轻松地从独立的子页面构建页面。它们还在样式和全局变量方面提供了很好的隔离度,不会相互干扰。

优点:

1.实现简单: 子应用之间自带沙箱,天然隔离,互不影响

2.技术不限制: 可以各自使用完全不同的前端框架;

3.消息传递: 只要每个 iframe 来自同一个来源,可以使用 Window.postMessageAPI 来进行消息传递;

缺点:

1.Bundle 的大小各异: 构建时也不能提取公共依赖关系;

2.无 SEO: 众所周知 iframe 对 SEO 是毁灭性的打击,单这一条即可否定该方案了;

3.URL 状态不同步: iframe 的页面 url 中的状态信息并不能同步到父窗口,无法使用浏览器的前进后退功能;

4.DOM 结构不共享: iframe 的页面布局只针对于 iframe 窗口(例如:全局弹框无法给出合理布局);

5.全局上下文完全隔离,内存变量不共享: iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的微应用中实现免登效果;

6.慢: 每次微应用进入都是一次浏览器上下文重建、资源重新加载的过程;

使用 Web Components 构建应用

Web Components 是一个 Web 标准,像 Angular、React/Preact、Vue 或 Hyperapp 这样的主流 JavaScript 框架都支持它们; 你可以将 Web Components 视为使用开放 Web 技术创建的可重用的用户界面小部件。

优点:

1.拥有自己独立的 Scripts 和 Styles,以及对应的用于单独部署子应用组件的域名;

2.代码的可读性变得非常清晰,组件资源内部高内聚,组件资源由自身加载控制;

缺点:

1.浏览器和框架的支持不够: 需要更多的 polyfills 从而影响到用户页面的加载体验;

2.重写现有的前端应用: 我们需要在整个前端应用上把它们全部转换成 Web Components;

3.系统架构复杂: 当应用被拆分为一个又一个的组件时,组件间的通讯就成了一个特别大的麻烦

Module Federation 模块联邦

webpack5 新增的 Module Federation(模块联邦)功能,他可以帮助将多个独立的构建组成一个应用程序,不同的构建可以独立的开发与部署,利用模块联邦我们可以在一定程度上去实现微前端。

优点:

1.开箱即用:只需要执行几行命令即可拉取相应的模板代码并把项目跑起来,包括基座应用和微前端应用,无需处理构建工具的复杂配置;

2.独立开发与部署:基于提供的代理工具,微应用开发者在单独开发微应用时,无需启动基座或者其它微应用;

3.去中心化: 因为采用的是模块共享,所以不用使用中心基座的概念;

4.组件共享: 与 npm 发包类似的组件共享管理;

缺点:

1.无法沙箱隔离: 需借助其它工具和框架才能做到应用层面的隔离;

2.技术单一: 仅限使用 webpack5 版本以上;

3.代码封闭性高: 依旧需要做npm那一套管理和额外的拉取代码,还不如直接 npm 复用方便;

4.拆分粒度需要权衡: 共享的 lib 无法做到 tree-shaking;

5.依赖前置: 导致时间加载变长;

组合式应用路由分发(中心基座方案)

当下微前端主要采用的是 组合式应用路由方案,该方案的核心是 主从 思想,即包括一个基座(MainApp)应用若干个微(MicroApp)应用; 基座应用大多数是一个前端SPA项目,主要负责 应用注册,路由映射,消息下发 等,而微应用是独立前端项目,这些项目不限于采用 React,Vue,Angular 或者 JQuery 开发,每个微应用注册到基座应用中,由基座进行管理,但是如果脱离基座也是可以单独访问。

优点:

1.技术不限制: 可以各自使用完全不同的前端框架;

2.无感切换: 因为是一个 SPA 项目,所以体验极佳;

3.利于SEO

4.独立开发与部署

5.微前端优势几乎都有

缺点:

1.沙箱不隔离: 也就是 js 与 css 样式会出现冲突的问题

小结一下

解决方案优点缺点
服务器路由重定向(通过 Nginx 配置代理映射到不同的子模板应用上)简单、快速、易配置在切换应用时会触发浏览器刷新,影响体验
iframe(iframe + 自定义消息传递)1. 实现简单 2. 技术不限制 3. 消息传递1. Bundle 的大小各异 2. 无 SEO 3. URL 状态不同步 4. DOM 结构不共享 5. 全局上下文完全隔离,内存变量不共享 6. 速度慢
Web Components1. 拥有自己独立的 Scripts 和 Styles,以及对应的用于单独部署子应用组件的域名; 2. 代码的可读性变得非常清晰,组件资源内部高内聚,组件资源由自身加载控制;1. 浏览器和框架的支持不够 2. 重写现有的前端应用 3. 系统架构复杂
Module Federation1. 开箱即用 2. 独立开发与部署 3. 去中心化 4. 组件共享1. 无法沙箱隔离 2. 技术单一 3. 代码封闭性高 4. 拆分粒度需要权衡 5. 依赖前置
组合式应用路由分发1. 技术不限制 2. 无感切换 3. 利于SEO 4. 独立开发与部署 5. 微前端优势几乎都有沙箱不隔离

微前端框架选型

目前市面上已经出现大量的优秀微前端框架,从singel-spa到各家研发的产品等等,这里推荐下京东出品的microApp,接入成本低,兼容性更强,性能已接近原生,欢迎大家的体验~

转载自:https://juejin.cn/post/7208057259053006906
评论
请登录