微前端架构技术解析

前言近来,微前端的概念非常火爆,那么什么是微前端架构?微前端架构是一种架构风格类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用 。由此带来的变化是,这些前端应用可以独立运行、独立开发、独立部署 。微前端所具备的便于引入新框架,代码简洁、易维护等特点使其应用愈发广泛 。
爱奇艺号前端工程基于Vue的框架已经使用了3年之余,这一版本虽有不错的可扩展性,但随着接入的业务越来越多,项目复杂度和代码行数增长,现有框架需要将框架与业务更加的解耦以方便其他团队进行维护,同时也需要模块的独立部署、发布等提高迭代效率 。基于种种原因,爱奇艺号技术团队基于Vue定制开发了微前端框架,此文从偏向实践的方面来简要介绍这套框架的实现原理 。
 
容器应用首先需要一个容器应用,这个容器应用需要有最基本的代码架构,比如Vue、主路由、Vuex及其他基础的通用代码,但需要将这些通用代码中任何业务相关的部分剥离 。简单来说,容器应用是一个基于Vue的框架,其作用是将其他分散的各个微前端模块通过页面路由攒在一起,再组成一个个的页面 。
除了基本的Vue启动应用等功能,微前端容器的架构逻辑需要做到下面几点:
1、将微前端模块需要的通用代码绑定至全局函数;
2、基于请求的url获取相对应的微前端模块部署的js manifest文件地址列表(列表manifest中包含业务自己定义的路由、js模块的地址列表);
3、通过匹配微前端模块中定义的路由获取页面所需的微前端模块;
4、加载每个微前端模块的具体js文件地址并将其渲染 。
下面我们来依次对容器应用中各个部分进行介绍:
- App.js
这一部分用于进行Vue的初始化的相关逻辑 。与正常Vue初始化逻辑相比,这里唯一不同的是需要将一些其他微前端模块必需的通用组件绑定到全局变量中(此处用window,也可以自己定义一个全局变量),比如:
· Vue:其他微前端模块都需要使用容器应用提供的Vue包初始化,而非每个微前端模块自己在package.json中引入Vue,这样会严重增加js包大小,拖累页面性能;
· Router:为了让微前端能够无缝跳转其他页面,统一使用全局路由,在子模块中定义的路由将会在加载页面时实时合并到主路由中;
· Store:很多不同小模块、大微前端模块之间的交互可以使用全局通用的Store;
· RenderPage模块:给其他微前端模块路由渲染页面使用的component(后文会详细讲这个模块);
· 其他的一些小模块,比如用户信息管理模块等.
在框架中,为了方便子模块的运行,全部通用组件被绑定到window下,如window.mp.Vue等,这为子模块按需取用提供便利 。
- hosts配置
因微前端容器应用中不引用任何子模块的依赖,需要直接通过正常url访问获取子模块的js代码,所以容器应用需要通过自定义的配置文件来获得每个子模块所在的服务器host,以便拼凑出需要加载的js具体路径 。每当增加一个新的模块,就需要在这里添加模块部署的相应地址,否则容器应用不会成功解析 。
例如:
 

微前端架构技术解析

文章插图
 
 
配置中可以包含多个不同服务器环境的地址,在不同的环境中自动使用相对应的url 。值得注意的是,本地环境build中使用localhost加port的地址,方便本地启动调试模块 。本地启动时,需要将容器应用以及全部微前端模块一起启动,页面才会正常运行 。
- 路由
在微前端中路由实现分治,即每个微前端模块(业务)维护各自的路由,容器应用负责匹配并拉取即将访问的页面相对应的模块及其路由 。在这里我们首先为主容器定义一个非常宽泛的路由定义,比如path: '*',然后在路由的钩子函数如beforeEach中实现微前端模块的路由获取,并将其添加进主路由中 。
 
微前端架构技术解析

文章插图
 
 
从子模块生成的manifest.json(后面微前端模块部分会介绍)中获取子模块的路由js文件并将其解析,再加入主路由中 。经过此番操作后,同一个窗口再次访问这个地址时就会直接匹配成功主路由了 。
- 微前端模块渲染
容器应用中最重要的部分就是如何获取并渲染微前端模块 。现提供一个module.vue模块专门负责拉取并渲染微前端模块,则module.vue需要做的事情如下:


推荐阅读