热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于微前端:理解微前端技术原理

我最早是在2016年接触到微前端的,过后社区里以介绍概念居多,在实际计划,尤其是在业务落地方面利用的比拟少。起初,随着计划逐步成熟,社区里对于微前端的探讨越来越多。

我最早是在 2016 年接触到微前端的,过后社区里以介绍概念居多,在实际计划,尤其是在业务落地方面利用的比拟少。起初,随着计划逐步成熟,社区里对于微前端的探讨越来越多。

明天,咱们先从概念、关键技术原理层面来对微前端进行具体阐明。后续会有专门的文章来介绍微前端的实践经验。

什么是微前端

微前端的概念来源于微服务,其整体的架构思路是将前端利用分解成一些更小、更简略的可能独立开发、测试、部署的利用,之后将这些利用组成整体,在用户看来依然是内聚的单个产品,用户体验是统一的。

从概念上看,微前端架构由主利用和子利用两个局部组成,子利用负责具体的业务实现,主利用负责子利用的加载和卸载,即生命周期治理。

从概念延长开来,咱们不难发现,应用微前端,能够取得如下收益:

  • 子利用独立开发、部署,技术栈无关
    拆分当前,子利用领有独立的代码仓库、独立的开发部署流程,甚至能够自在的应用任何技术栈进行开发。由此,咱们能够在组织架构层面造成不同的团队来负责不同的业务模块,各个团队之间绝对独立自主,互不烦扰。
  • 增量降级,多技术体系共存
    对于很多大型的组织,他们的产品通常都经验了长期的迭代,性能简单,同时技术栈通常也比拟老旧。应用微前端当前,借助于独立的子利用,能够取得增量降级的能力。既能够实现新性能应用新的技术栈,同时与老技术栈共存。又能够对老性能进行逐渐迭代降级,小步快跑。
  • 产品层面的自由组合
    借助于微前端,咱们能够对各个子利用自在的进行高低线。换句话说,咱们能够依据产品须要,自在的将不同的子利用组合成新的产品。

技术剖析

在微前端架构下,有主利用和子利用两个根本角色。子利用负责具体的业务逻辑,主利用负责调度子利用。思考到主利用的特殊性性能,为了保障整个框架的可用性,通常主利用不负责任何业务逻辑。

路由与子利用加载

因为主利用负责调度子利用,因而主利用须要具备路由治理和资源加载能力。所谓路由治理,就是主利用中须要保护一个路由表,当页面路由发生变化的时候,主利用能够晓得以后须要启动哪个子利用。这个路由表能够是动静的,也能够是动态的。

晓得启动哪个子利用之后,主利用就须要加载子利用的资源。通常有两种资源加载形式:

  • JS Entry。
    通常将子利用的所有资源打包成一个入口文件,在 single-spa 的很多样例中就应用了这种形式。
  • HTML Entry。
    子利用构建输入的是一个 HTML 文件,主利用通过加载这个 HTML 文件实现子利用的加载。

相比较而言,JS Entry 的计划限度更多一些,比方要求将图片、款式等所有资源打包成一个 JS Bundle,构建的包太大,也无奈利用浏览器的并行加载能力。同时,子利用还须要与主利用约定好要挂载的节点,主利用要提前初始化好,或者子利用自行创立,防止挂载失败或者抵触。

HTML Entry 很好的防止了 JS Entry 的问题。实质上,HTML 文件充当的是利用动态资源表的角色。主利用加载了 HTML 当前,浏览器会自行下载子利用的各种资源。同时,因为构建产物是 HTML,子利用具备与独立利用开发时统一的开发体验。当然,HTML Entry 也存在毛病,比方要多一次申请,先加载了 HTML 能力晓得加载哪些资源。

在加载完子利用的资源当前,主利用就能够启动子利用,实现页面渲染了。那么该如何启动子利用呢?主利用须要与子利用之前制订一个接口标准,比方在 single-spa 中就指定了 bootstrapmountunmountunload 四个办法。子利用裸露这四个办法给主利用,主利用通过这四个办法来治理子利用的申明周期。

隔离

解决了路由和子利用加载的问题,实践上说咱们曾经实现了微前端的外围能力。然而,在理论的工程实际中,咱们还须要解决很多的细节问题。其中最大的一部分就是如何做好子利用间的隔离。比方如何防止子利用间的款式抵触。

抛开现有的微前端计划,如果让咱们从头开始实现一套微前端架构,将独立开发部署的各个子利用组合起来。置信大多数同学都会首先想到 iframe。其实咱们就能够通过 iframe 来了解微前端架构中的种种技术细节。

iframe 自带的款式、环境隔离机制使得它具备人造的沙箱能力,然而 iframe 也有很多人造的缺点,比方事件无奈冒泡到顶层,路由跳转无奈与主利用同步,与主利用通信简单繁琐等。

咱们能够参考 iframe 的设计思维,来设计如何对子利用进行隔离。一个传统的 iframe 具备四层能力:文档的加载能力、HTML 的渲染能力、独立执行 Javascript 的能力、隔离款式的能力。

文档的加载能力和 HTML 的渲染能力在后面主利用加载子利用资源的时候,咱们曾经做了阐明。

咱们当初来说说如何实现独立的 Javascript 运行环境和款式隔离。

沙箱(sandbox)

通常,子利用在运行期间会有一些污染性的副作用产生,比方全局变量、全局事件、定时器、网络申请、localStorage、全局 Style 款式、全局 DOM 元素等。为了保障利用可能稳固的运行且互不影响,须要提供平安的运行环境,可能无效地隔离、收集、革除利用在运行期间所产生的副作用,也就是沙箱的设计指标。

有两种沙箱的设计思路。一种是快照模式,另一种是虚拟机(virtual machine)模式。

快照模式

所谓快照模式,就是将启动子利用之前,对以后环境打一个快照,子利用退出之后,再从新加载这个快照来复原环境。

在实现层面,咱们能够针对每一种副作用设计一个 save 办法保留以后状态,在设计一个 load 办法来加载保留的状态。

框照模式的缺点是对操作的程序要求十分严格,当页面有多个子利用的时候,快照沙箱就会有多个实例存在,此时不同程序的 saveload 会产生问题。

VM(虚拟机)模式

虚拟机想必大家都据说过,是一种计算机系统的仿真器,通过软件模仿具备残缺硬件零碎性能的、运行在一个齐全隔离环境中的残缺计算机系统。应用虚拟机就跟应用实在的计算机一样。

NodeJS 中也提供了 VM 模块,不过不同于传统的 VM,它并不具备虚拟机那么强的隔离性,并没有模仿残缺的硬件零碎,仅仅将指定代码搁置了特定的上下文中编译并执行,无奈用来执行不可信起源的代码。

上面的代码展现了 NodeJS 的 VM 模块的根本用法:

const vm = require('vm');

const x = 1;

const cOntext= { x: 2 };
vm.createContext(context); // 将 context 对象高低文化

const code = 'x += 40; var y = 17;';
// `x` and `y` 在上下文中是全局变量
// 初始状态下, x 的值为 2,因为 context.x 得值是 2
vm.runInContext(code, context);

console.log(context.x); // 42
console.log(context.y); // 17

console.log(x); // 1; y 为未定义

参考 NodeJS 中 VM 模块的设计,以及 Javascript 词法作用域的个性,能够设计出 VM 沙箱,不过与传统的 VM 差别也同样存在,它并不能执行不可信的代码,因为它的隔离能力仅限于将其运行在一个指定的上下文环境中。

let code = `(function(document, window){ /* 代码逻辑 */ })`

(new Function('document', 'window', code)(fakeDocument, fakeWindow))

针对后面提到的子利用运行产生的全局变量、全局事件等种种副作用,咱们能够针对性的做解决,提供新的执行上下文。比方,用新的 window 对象用来隔离全局变量,用新的 document 来收集创立的 dom 对象,style 款式,script 标签等。全局事件、localStorage 等都能够一一进行解决。

上面借助于 Proxy,咱们能够轻松的对以后的执行上下文进行劫持,创立新的执行上下文。上面的代码展现了如何劫持 window 对象。

const varBox = {};
const fakeWindow = new Proxy(window, {
  get(target, key) {
    return varBox[key] || window[key];
  },
  set(target, key, value) {
    varBox[key] = value;
    return true;
  }
});

const code = `(function(window) {
  window.a = '111';
  console.log(window.a);
})`;

const fn = new Function('window', code);
fn(fakeWindow);

VM 模式的沙箱,能够无效的解决子利用之间、奴才利用之间各种副作用的无效隔离问题。qiankun 的沙箱模式就是 VM 模式。

款式隔离

尽管说,VM 模式的沙箱能够收集子利用运行过程中产生的款式,而后在子利用卸载的时候去除款式,然而思考到子利用的 dom 构造最终还是要并入到主利用的 dom 树中去,VM 沙箱无奈防止主利用的款式烦扰到子利用的款式的问题。

这时候,咱们就须要借助于一些其余伎俩,比方在奴才利用中都应用 css modules 来缩小款式抵触。

Shadow Dom

如果不思考兼容性,Shadow Dom 是子利用款式隔离的一个绝佳抉择。

咱们把子利用放到 Shadow Dom 中,能够原生实现子利用间的款式隔离。然而 Shadow Dom 自身也有诸多限度,很多依赖库还不反对 Shadow Dom。比方埋点检测,事件处理等。

咱们这里仅是将 Shadow Dom 作为补充技术计划来进行阐明。

qiankun 官网也将在将来的版本中逐渐弃用 Shadow Dom。

须要留神的问题

技术畛域有句话叫“没有永远的银弹”。本文结尾咱们介绍了应用微前端能够取得的很多收益,当初咱们来讲讲微前端带来的问题。

  • 整个产品的复杂度从代码转移到了基础设施
    咱们须要有一套利用注册、治理的零碎,并要和现有的利用公布流程对接。同时还要围绕微前端计划构建一整套的根底工具,比方开发调试工具,埋点监控零碎等。
  • 减少了学习和了解老本
    子利用或多或少要理解一些微前端计划的技术原理,能力带来更好的开发和产品体验。

常见面试知识点、技术解决方案、教程,都能够扫码关注公众号“众里千寻”获取,或者来这里 https://everfind.github.io 。


推荐阅读
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 在使用 Qt 进行 YUV420 图像渲染时,由于 Qt 本身不支持直接绘制 YUV 数据,因此需要借助 QOpenGLWidget 和 OpenGL 技术来实现。通过继承 QOpenGLWidget 类并重写其绘图方法,可以利用 GPU 的高效渲染能力,实现高质量的 YUV420 图像显示。此外,这种方法还能显著提高图像处理的性能和流畅性。 ... [详细]
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
  • 深入浅出 webpack 系列(二):实现 PostCSS 代码的编译与优化
    在前一篇文章中,我们探讨了如何通过基础配置使 Webpack 完成 ES6 代码的编译。本文将深入讲解如何利用 Webpack 实现 PostCSS 代码的编译与优化,包括配置相关插件和加载器,以提升开发效率和代码质量。我们将详细介绍每个步骤,并提供实用示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • C++ 异步编程中获取线程执行结果的方法与技巧及其在前端开发中的应用探讨
    本文探讨了C++异步编程中获取线程执行结果的方法与技巧,并深入分析了这些技术在前端开发中的应用。通过对比不同的异步编程模型,本文详细介绍了如何高效地处理多线程任务,确保程序的稳定性和性能。同时,文章还结合实际案例,展示了这些方法在前端异步编程中的具体实现和优化策略。 ... [详细]
  • 本文详细介绍了如何利用CSS技术对链接下划线进行个性化定制和美化,涵盖了多种实用技巧和方法。通过对CSS属性的灵活运用,可以实现不同风格的下划线效果,提升网页的视觉体验。文中不仅提供了基础的代码示例,还结合实际案例进行了深入解析,帮助读者更好地理解和应用这些技巧。此外,文章还引用了《CSS2.0中文手册》中的相关内容,增加了技术的权威性和实用性。 ... [详细]
  • 当使用 `new` 表达式(即通过 `new` 动态创建对象)时,会发生两件事:首先,内存被分配用于存储新对象;其次,该对象的构造函数被调用以初始化对象。为了确保资源管理的一致性和避免内存泄漏,建议在使用 `new` 和 `delete` 时保持形式一致。例如,如果使用 `new[]` 分配数组,则应使用 `delete[]` 来释放内存;同样,如果使用 `new` 分配单个对象,则应使用 `delete` 来释放内存。这种一致性有助于防止常见的编程错误,提高代码的健壮性和可维护性。 ... [详细]
  • 在当前的软件开发领域,Lua 作为一种轻量级脚本语言,在 .NET 生态系统中的应用逐渐受到关注。本文探讨了 Lua 在 .NET 环境下的集成方法及其面临的挑战,包括性能优化、互操作性和生态支持等方面。尽管存在一定的技术障碍,但通过不断的学习和实践,开发者能够克服这些困难,拓展 Lua 在 .NET 中的应用场景。 ... [详细]
  • 使用 Vuex 管理表单状态:当输入框失去焦点时自动恢复初始值 ... [详细]
  • C++ 开发实战:实用技巧与经验分享
    C++ 开发实战:实用技巧与经验分享 ... [详细]
  • JavaScript XML操作实用工具类:XmlUtilsJS技巧与应用 ... [详细]
  • 深入解析:React与Webpack配置进阶指南(第二部分)
    在本篇进阶指南的第二部分中,我们将继续探讨 React 与 Webpack 的高级配置技巧。通过实际案例,我们将展示如何使用 React 和 Webpack 构建一个简单的 Todo 应用程序,具体包括 `TodoApp.js` 文件中的代码实现,如导入 React 和自定义组件 `TodoList`。此外,我们还将深入讲解 Webpack 配置文件的优化方法,以提升开发效率和应用性能。 ... [详细]
author-avatar
怪兽朴朴朴
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有