现代的前端应用的发展趋势正在变得越来越富功能化,富交互化。复杂的单体前端应用背后则是数量庞大的后端应用组成的微服务集群。在一个团队中维护的前端项目,随着时间推进,会变得越来越庞大,越来越难以维护。所以我们给这种应用起名为巨石单体应用。
反观后端技术的发展趋势,从最初的前后端混合开发到前后端分离再到现在的微服务拆分。原本臃肿的后端服务在以垂类方向拆分之后变得清晰易维护。
微前端正是借鉴了微服务的架构理念,摒弃大型单体方式,将前端整体分解为小而简单的块,这些块可以独立开发、测试和部署,同时仍然聚合为一个产品出现在客户面前。可以理解微前端是一种将多个可独立交付的小型前端应用聚合为一个整体的架构风格。
简单来说:微前端是一种架构风格,将独立交付的前端应用程序组合成一个更大的整体。保证产品体验的同时提升开发体验。
目前较为流行的微前端架构的实现方案:在主应用中通过 loader 加载子应用,通过 router 判断子应用的加载时机,通过 store 来处理跨应用间的数据共享。在用户无感知的情况下将前端应用拆分为可独立运行、维护的多个子应用。
严格意义上来说 MPA 可能不算是标准的微前端方案,用户在使用过程中可能会存在一些体验上的割裂感。就好比去超市买菜,MPA 超市的服务员告诉你:“白菜我们这没有了,我给你个地址你去其他店买吧。”虽然最终也买到了,但是花费了更多时间。
更好的做法应该是:“白菜我们这没有了,我立刻帮你从其他超市进货过来。”用户不用经历 出超市->找路->进超市 的过程就买到了菜。
将系统分为多个仓库维护,在首页聚合所有平台的入口或提供统一的导航组件,采用 MPA(Multi-page Application)多页应用模式。
如下图所示应用的导航部分记录了所有子应用的入口地址,用户点击后会跳转到对应的子平台地址。公共导航部分需要抽离成组件给子平台使用。
微前端场景下的缺陷:
经历过早期前端开发的同学可能都会有印象,在 webpack、react、vue 等框架大行其道前。我们常会使用 hbs、ejs 等页面模板框架来开发我们的前端页面。在服务端根据请求路径做静态模板拼接,来返回相应的页面结构。
假设我们有一个 index.html,它包含任何公共的页面元素,然后使用服务器端 include 从片段 HTML 文件插入特定于页面的内容。最终你会得到一个如下右图所示的页面结构(虽然看着比较奇怪,但确实可以运行)。
由此可见虽然微前端是一个较新的概念但是它的实现方式并非一定需要依赖新的技术。
通过将子应用打包为 npm 包,在主应用中作为依赖库引入。
微前端场景下的缺陷:
模块联邦是一个 webpack5 提供的新特性。既可以做到打包发布模块供给后,消费者能够实时保持同步,也可以进行代码构建时候的优化。可以在一个应用中直接导出或使用另一个应用的模块。(详见1[1])
EMP 是一个基于模块联邦能力的微前端框架,每一个微前端应用都通过远程调用的方式引入共享模块。在实现微前端能力的同时很好的处理了共享模块重复引用的问题减少了整体项目体积,同时也带来了构建速度的提升。
虽然 EMP 较好的解决了子应用动态更新的问题,但从实际微前端使用场景来说还需要考虑子应用间的相互影响,需要处理 JS 沙箱、CSS 隔离等问题。EMP 的方案更适用于微组件而非微应用的场景。
在浏览器中组合应用程序的最简单的方法之一就是 iframe。从本质上讲,iframe 使从独立的子页面构建页面变得很容易。它们还在样式和全局变量不相互干扰方面提供了良好的隔离程度。但他的最大问题也在于他的隔离性无法被突破,导致应用间上下文无法被共享,随之带来的开发体验、产品体验的问题。
微前端场景下的缺陷:
有没有方法在保留 iframe 优点的同时,解决 iframe 的痛点问题?见下文
通过 JS 加载子应用是最灵活的方法,也是目前最常采用的方法。每个子应用按约定暴露出相应的生命周期钩子,并且在加载后将其绑定到 window 对象下给主应用访问。然后主应用程序确定渲染哪个子应用,调用相关渲染函数传入渲染节点。(以下代码仅做示意)
基于 single-spa 实现路由与子应用的绑定关系根据路由加载相应应用。子应用将自己的信息注册到主应用中,包括入口文件地址、对应生效路由及命名空间等信息。同时子应用需暴露几个关键的生命周期钩子bootstrap
、mount
、unmount
,以供主应用在适当的时机调用。
提供两套 JS 沙箱方案(具体实现方案见下文):
CSS 隔离方案(具体实现方案见下文):
通过为每个 css 规则添加特定的前缀来起到隔离的作用,例如微应用中的样式是 p{color:#000} ,处理后为 .app1 p {color:#000} 。
相比而言乾坤是目前微前端框架中比较成熟且用户最多的框架了,基本解决了大部分微前端开发中会遇到的问题。但是也存在一些接入成本,需要对子应用做一些改造(umd 打包,暴露 hook 等)。
基于 iframe 实现 js 沙箱,通过 WebComponent 处理 css 隔离。(详见2[2])
大致实现方式为:运行时动态加载子应用资源(加载方式在下文技术细节中会详细说明),在主应用中创建一个 shadowdom 节点和一个 iframe。将 js 注入 iframe 内运行,将 dom、css 放到 shadowdom 节点下。同时劫持 js 中的 dom 操作并指向 shadowdom。
在路由状态方面 通过劫持iframe
的history.pushState
和history.replaceState
将子应用的url
同步到主应用的query
参数上,当刷新浏览器初始化iframe
时,读回子应用的url
并使用iframe
的history.replaceState
进行同步。
区别于上一种方式,WebComponent 的实现将子应用包裹为一个 HTML 自定义元素供容器实例化,而不是要求子应用暴露一些供容器调用的全局函数,同时借助于 shadowdom 的隔离能力可以有更好的样式隔离性。
micro-app
借鉴了 WebComponent 的思想,通过 CustomElement 结合自定义的 ShadowDom,将微前端封装成一个类 WebComponent 组件,从而实现微前端的组件化渲染。并且由于自定义 ShadowDom 的隔离特性,micro-app
不需要像single-spa
和qiankun
一样要求子应用修改渲染逻辑并暴露出方法,也不需要修改 webpack 配置,接入成本较低。
需要注意的是 shadowDOM 在 React 框架及一些 UI 库中的兼容不是很好,经常会出现一些不可预料的问题。如在 react16 及以下的版本中,在 shadowDOM 下绑定合成事件时会出现不触发的情况。(详见3[3])
实际在 micro-app 中默认也不会开启 shadowDOM 的能力。
本文中的技术细节主要参考乾坤为主,各框架内部实现各有差异,但总体方向上不会有太大的区别
目前单页应用使用路由的方式分为两种:hash 模式,history 模式。这两种方式中都无法完全依赖单个原生事件来覆盖所有场景需要做一些兼容工作。
我们除了需要监听popstate
、hashchange
这两个事件外。在调用 pushState
以及 replaceState
也会造成路由变化,但不会触发事件,因此我们还需要去重写这两个函数。
渲染子应用的第一步首先要加载子应用资源,我们可以通过应用注册时的 entry 字段拿到资源入口。这里入口资源加载分为两种方案:(详见4[4])
{
template: 经过处理的dom结构,link、script 标签都被注释掉了,
scripts: [脚本的http地址 或者 { async: true, src: xx } 或者 代码块],
styles: [样式的http地址],
entry: 入口脚本的地址,要不是标有 entry 的 script 的 src,要不就是最后一个 script 标签的 src
}
import-html-entry 的加载过程:
2. 通过 proxy(或 defineproperty)劫持对 window 的操作并创建一个 fakeWindow 对象,赋值操作都发生在 fakeWindow 对象下,取值时按照 fakeWindow -> window 的顺序依次查找。
在应用切出/卸载后,同时卸载掉其样式表即可,原理是浏览器会对所有的样式表的插入、移除做整个 CSSOM 的重构,从而达到 插入、卸载 样式的目的。这样即能保证,单应用场景下在一个时间点里,只有一个应用的样式表是生效的。
2 . 编译改造
提供一个 postcss 插件,在应用构建的时候给所有的样式都加上应用前缀包括应用公共库的 CSS。
3 . 域隔离
为每个 css 规则添加特定的前缀来起到隔离的作用,例如微应用中的样式是 p{color:#000} , 处理后为 .app1 p {color:#000} 。(源码实现[5])
最后引用玉伯的一句话来总结:今天看各 BU 的业务问题,微前端的前提,还是得有主体应用,然后才有 微组件 或 微应用 ,解决的是可控体系下的前端协同开发问题(含空间分离带来的协作和时间延续带来的升级维护)。
[1]详见1: https://webpack.docschina.org/concepts/module-federation
[2]详见2: https://wujie-micro.github.io/doc/guide/
[3]详见3: https://github.com/facebook/react/issues/10422
[4]详见4: https://juejin.cn/post/6885212507837825038
[5]源码实现: https://github.com/umijs/qiankun/blob/master/src/sandbox/patchers/css.ts
[6]Why Not Iframe · 语雀: https://www.yuque.com/kuitos/gky7yw/gesexv?from=from_parent_mindnote
[7]从零到一实现企业级微前端框架,保姆级教学 - 掘金: https://juejin.cn/post/7004661323124441102#heading-1
[8]Micro Frontends: https://martinfowler.com/articles/micro-frontends.html
[9]MicroApp: https://zeroing.jd.com/micro-app/docs.html#/
[10]介绍 - qiankun: https://qiankun.umijs.org/zh/guide
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/wlO5xaMz_DYYy01VkCRkZA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。