微前端模块联邦实践系列(1) - 微前端入门

406 阅读8分钟

本系列大纲

写在前面

最近在研究关于微前端方面的知识,对Webpack Module Federation如何实现微前端做了一系列的demo,学习的主要来源为Stephen Grider的微前端课程(付费课程,无法share链接),同时在此基础上根据自己的理解,做了一些以及扩充,这里作为记录并且分享出来。

本系列主要为实践篇,每篇文章中会采用较小的篇幅来讲解一到两个知识点,或者问题的解决思路等等。前面几个篇幅会主要引入一些概念,感兴趣的可以看看,不想看具体的也可以看看TOC,基本就可以了解这篇文章大致讲了什么,然后挑自己感兴趣的具体看看。

微前端的基本概念

微前端(Micro Frontends)是一种架构风格,将传统的单体前端应用拆分为多个独立、自治的小型前端应用,每个小型应用可以由不同的团队独立开发、部署,并以某种方式组合在一起,构成一个完整的前端界面。这种方法类似于后端的微服务架构,使得前端开发更加灵活,能够更好地应对复杂应用的需求和不同团队的协作。

微前端的核心思想包括:

  1. 独立开发和部署:每个微前端模块可以独立开发、测试和部署,不需要依赖整个应用。这使得团队之间的协作更高效。
  2. 技术栈无关:各个微前端模块可以使用不同的技术栈(React、Vue、Angular等),这为团队选择最适合的工具提供了灵活性。
  3. 应用组合:不同的微前端模块可以通过模块联邦(Module Federation)等技术组合在一起,实现最终的用户体验。

微前端在像大型企业和复杂应用场景中尤其有用。比如,多个团队可以分别负责一个具体的业务模块,这样可以加快开发速度并降低依赖性。

微前端产生的背景

微前端的背景源于前端应用复杂性逐渐增加的需求,特别是在大型企业级应用中。随着前端技术的发展,单页应用(SPA)越来越复杂,传统的前端开发模式开始遇到一些瓶颈,如:

  1. 单体应用的复杂性:随着项目规模增长,前端代码库变得庞大且难以维护,多个团队在同一个代码库中开发导致冲突和效率低下。
  2. 独立部署困难:在单体前端架构中,任何一个小改动都需要重新部署整个应用,增加了风险和发布成本。
  3. 团队协作障碍:大型项目中,多个团队使用相同的技术栈,限制了团队选择适合自己业务场景的技术,也增加了相互之间的依赖性。

为了应对这些挑战,微前端架构应运而生,借鉴了后端微服务的理念,将前端应用拆分为更小、更易于管理的独立模块。每个微前端模块可以独立开发、测试和部署,降低了团队之间的耦合度,同时还提供了更高的灵活性和可扩展性。

微前端的出现大大提高了团队协作效率,使得前端开发能够更好地应对现代复杂的应用需求。

微前端目前有哪些实现方式

微前端有多种实现方式,每种方式都有其适用的场景和技术栈选择。以下是一些常见的微前端实现方式及其具体举例:

1. 基于 iframe 的微前端

这是最简单和传统的微前端实现方式,利用 iframe 将不同的前端应用嵌入到同一个页面中。每个 iframe 都是一个独立的子应用,完全隔离,不会干扰其他子应用。

优点

  • 完全隔离,避免了不同应用之间的冲突(如 CSS 和 JavaScript 全局变量)。
  • 易于实现,不需要对原有系统进行大规模改造。

缺点

  • 不利于用户体验,页面间的跳转不流畅。
  • 共享状态和数据较为复杂。

2. 基于 Web Components 的微前端

Web Components 是浏览器原生支持的一种技术,用于封装组件并确保其独立性。利用 Web Components,可以将微前端应用作为独立的组件插入到页面中。

优点

  • 原生浏览器支持,不需要额外的框架。
  • 组件完全隔离,避免了样式和 JavaScript 变量冲突。
  • 支持不同的技术栈,子应用可以用 React、Vue、Angular 或其他框架开发。

缺点

  • 浏览器兼容性较旧,但随着现代浏览器的普及,已经越来越普遍。
  • 管理复杂交互时可能需要额外的工作。

3. 基于 Module Federation 的微前端

这是 Webpack 5 引入的一种现代微前端实现方式。Module Federation 允许应用程序动态加载和共享代码模块,多个子应用可以相互共享组件和库。

优点

  • 允许多个应用共享依赖,减少重复加载。
  • 动态加载模块,灵活性高。
  • 适合模块化程度高的场景,可以极大提升开发和运行效率。

缺点

  • 对构建工具有较高要求,需要熟悉 Webpack 和微前端模块化的配置。
  • 子应用之间的耦合性需要谨慎管理,避免滥用共享代码导致应用不稳定。

4. Single-SPA

Single-SPA 是一个微前端框架,支持将多个前端应用(使用不同框架)集成到同一个页面中。它允许每个子应用使用不同的前端框架,并处理这些应用的生命周期(加载、卸载等)。

优点

  • 支持多框架,可以在同一个页面中同时使用 React、Vue、Angular 等应用。
  • 管理应用的生命周期,使得子应用之间的加载和卸载更灵活。

缺点

  • 需要学习和配置 Single-SPA 的框架,增加了开发和维护的复杂度。

Build-time Integration & Run-time Integration

在微前端架构中,集成方式主要分为两种:构建时集成(Build-time Integration)运行时集成(Run-time Integration)。这两种方式的差别在于微前端应用的集成时机,以及如何管理这些应用之间的依赖和通信。

1. 构建时集成(Build-time Integration)

这种方式下,所有的微前端应用在构建阶段就已经集成在一起,生成一个单一的构建产物。应用的代码在构建时进行打包,最终的产物是一个包含所有微前端模块的应用。
特点:

  • 依赖固定:不同的微前端模块的依赖在构建时已经确定,因此版本冲突少。
  • 性能更好:因为所有模块都已经在构建阶段整合,运行时不需要再加载不同的模块,减少了加载时间和网络请求。
  • 紧耦合:微前端模块之间的耦合较紧,需要统一的构建工具链和配置管理。

优点:

  • 性能更好,减少了运行时模块加载的开销。
  • 适合依赖和版本关系比较复杂的项目。

缺点:

  • 缺少灵活性,难以动态地更新或替换独立模块。
  • 当某个模块发生变化时,通常需要重新构建整个应用。

示例技术

  • Monorepo(例如通过 Lerna 或 Nx 管理多个微前端模块的构建)

2. 运行时集成(Run-time Integration)

在这种方式下,微前端应用在运行时才被加载和集成。每个微前端应用都是独立的,可以动态加载和更新。这种方式通常通过 JavaScript 进行懒加载,或者通过 iframe 等方式来集成多个独立应用。

特点:

  • 动态加载:微前端模块可以在运行时按需加载,并且可以独立更新或替换。
  • 松耦合:每个微前端模块可以独立开发和部署,彼此之间的耦合较低。
  • 依赖问题:因为在运行时才集成,可能会出现模块依赖冲突(例如不同版本的库)。

优点:

  • 灵活性高,支持独立部署和实时更新。
  • 更容易实现多个团队同时开发和维护不同模块。

缺点:

  • 运行时性能可能不如构建时集成,因为每个模块需要在运行时加载。
  • 需要更复杂的依赖管理,防止依赖冲突。

示例技术

  • Webpack 5 模块联邦(Module Federation)
  • Single-SPA
  • iframe 基于 URL 的集成方式

总结来说,构建时集成更适合依赖关系复杂、追求性能的项目,而运行时集成则更适合需要动态加载、独立部署、灵活性高的场景。