微前端架构

文章目录

  • 微前端架构
    • 一. 什么是微前端
    • 二. 微前端的优势
    • 三. 微前端的多种实现
      • 3.1 iframe
      • 3.2 服务端模板组合
      • 3.3 微前端框架 single-spa
      • 3.4 微前端框架 qiankun

微前端架构

后端有微服务框架,当然前端也有微前端框架。

一. 什么是微前端

  • “微前端架构”就是构建基于微服务的前端应用架构

  • 其思想是将前端应用切分为一系列可以单独部署的松耦合的应用,然后将这些应用组装起来创建单个面向用户的应用程序

二. 微前端的优势

  1. 降低代码耦合
  2. 独立开发、独立部署
  3. 增量升级:微前端是一种非常好的实施渐进式重构的手段和策略
  4. 独立运行时,每个微应用之间状态隔离,运行时状态不共享
  5. 团队可以按照业务垂直拆分更高效

三. 微前端的多种实现

3.1 iframe

iframe 天然具备微前端的基因。我们只需将单体的前端应用,按照业务模块进行拆分,分别部署。最后通过 iframe 进行动态加载即可。

Demo:

<html>
  <head>
    <title>微前端-ifametitle>
  head>
  <body>
    <h1>我是容器h1>
    <iframe id="mfeLoader">iframe>
    <script type="text/javascript">
      const routes = {
        '/': 'https://app.com/index.html',
        '/app1': 'https://app1.com/index.html',
        '/app2': 'https://app2.com/index.html',
      };

      const iframe = document.querySelector('#mfeLoader');
      iframe.src = routes[window.location.pathname];
    script>
  body>
html>

优点:

  • 实现简单
  • 天然具备隔离性

缺点:

  • 主页面和 iframe 共享最大允许的 HTTP 链接数。
  • iframe 阻塞主页面加载。
  • 浏览器的后退按钮无效

3.2 服务端模板组合

常见的实现方式是,服务端根据路由动态渲染特定页面的模板文件。架构图如下:
微前端架构_第1张图片

优点:

  • 实现简单
  • 技术栈独立

缺点:

  • 需要额外配置 Nginx
  • 前后端分离不彻底

3.3 微前端框架 single-spa

微前端架构_第2张图片
借助 single-spa,开发者可以为不同的子应用使用不同的技术栈,比如子应用 A 使用 vue 开发,子应用 B 使用 react 开发,完全没有历史债务。

single-spa 的实现原理并不难,从架构上来讲可以分为两部分:子应用容器应用

子应用与传统的单页应用的区别在于:

  • 不需要 HTML 入口文件,
  • js 入口文件导出的模块,必须包括 bootstrap、mount 和 unmount 三个方法。

容器应用主要负责注册应用,当 url 命中子应用的路由时激活并挂载子应用,或者当子应用不处于激活状态时,将子应用从页面中移除卸载。其核心方法有两个:

  • registerApplication 注册并下载子应用
  • start 启动处于激活状态的子应用。

容器应用代码

<html>
<body>
    <script src="single-spa-config.js">script>
body>
html>

single-spa-config.js 代码如下:

import * as singleSpa from 'single-spa';
const appName = 'app1';
const app1Url = 'http://app1.com/app1.js'

// loadJS 方法是伪代码,表示加载 app1.js。开发者需要自己实现,或者借助 systemJS 来实现。
singleSpa.registerApplication('app1',() => loadJS(app1Url), location => location.pathname.startsWith('/app1'))

singleSpa.start();

子应用代码:

//app1.js
let domEl;
export function bootstrap(props) {
    return Promise
        .resolve()
        .then(() => {
            domEl = document.createElement('div');
            domEl.id = 'app1';
            document.body.appendChild(domEl);
        });
}
export function mount(props) {
    return Promise
        .resolve()
        .then(() => {
            domEl.textContent = 'App 1 is mounted!'
        });
}
export function unmount(props) {
    return Promise
        .resolve()
        .then(() => {
            domEl.textContent = '';
        })
}

优点:

  • 纯前端解决方案
  • 可以使用多种技术栈
  • 完善的生态

缺点:

  • 上手成本高
  • 需要改造现有应用
  • 跨应用的联调变得复杂

3.4 微前端框架 qiankun

qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。

在主应用中注册微应用

import { registerMicroApps, start } from 'qiankun';

registerMicroApps([
  {
    name: 'react app', // app name registered
    entry: '//localhost:7100',
    container: '#yourContainer',
    activeRule: '/yourActiveRule',
  },
  {
    name: 'vue app',
    entry: { scripts: ['//localhost:7100/main.js'] },
    container: '#yourContainer2',
    activeRule: '/yourActiveRule2',
  },
]);

start();

当微应用信息注册完之后,一旦浏览器的 url 发生变化,便会自动触发 qiankun 的匹配逻辑,所有 activeRule 规则匹配上的微应用就会被插入到指定的 container 中,同时依次调用微应用暴露出的生命周期钩子。

微应用需要在自己的入口 js (通常就是你配置的 webpack 的 entry js) 导出 bootstrapmountunmount 三个生命周期钩子,以供主应用在适当的时机调用。

/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap() {
  console.log('react app bootstraped');
}

/**
 * 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
 */
export async function mount(props) {
  ReactDOM.render(<App />, props.container ? props.container.querySelector('#root') : document.getElementById('root'));
}

/**
 * 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
 */
export async function unmount(props) {
  ReactDOM.unmountComponentAtNode(
    props.container ? props.container.querySelector('#root') : document.getElementById('root'),
  );
}

/**
 * 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
 */
export async function update(props) {
  console.log('update props', props);
}

优点:

  • 简单:qiankun 对于用户而言只是一个类似 jQuery 的库,你需要调用几个 qiankun 的 API 即可完成应用的微前端改造
  • 解耦/技术栈无关
  • 完善的生态

缺点:

  • 上手成本高
  • 需要改造现有应用
  • 跨应用的联调变得复杂

你可能感兴趣的:(前端学习)