探索微前端的三种技术方案

什么是微前端

首先我们应该先知道什么是微服务

微服务是面向服务架构(SOA)的一种变体,把应用程序设计成一系列松耦合的细粒度服务,并通过轻量级的通信协议组织起来,具体地,将应用构建成一组小型服务。这些服务都能够独立部署、独立扩展,每个服务都具有稳固的模块边界,甚至允许使用不同的编程语言来编写不同服务,也可以由不同的团队来管理。
探索微前端的三种技术方案_第1张图片

那么以微服务来类比,微前端也可以采用这种架构思想,将一个前端应用拆解成多个微应用,可独立开发、测试、部署,呈现给用户的是一个产品,内部原理实则是多个应用的集成或者内聚。

微前端核心思想

探索微前端的三种技术方案_第2张图片

  • 每个团队可以根据自己的技术栈来进行开发,各团队之间互不干扰,节省团队之间的技术沟通成本
  • 即使各团队使用相同技术栈,彼此也不应该共享变量和状态
  • 利用前缀的方式来区分不同项目之间CSS、Browser API、Web Event、Cookies 或 Local Storage之间的冲突
  • 使用浏览器事件进行通信,而不是构建一个全局的PubSub系统。如果你真的需要构建一个跨团队的API,尽量让它简单
  • 即使 JavaScript 失败或尚未执行,Web 应用程序的功能仍应有效。可以使用通用渲染和渐进增强来提高用户的感知性能

    微前端有哪些好处

    探索微前端的三种技术方案_第3张图片

  • 灵活性:技术栈无关,每个微应用可以是不同的技术栈
  • 渐进性:增量升级,便于项目扩展和重构
  • 独立性:每个微应用之间状态隔离,运行时状态不共享
  • 敏捷性:独立开发、独立部署,部署完之后主框架自动完成同步更新

微前端的三种实现方案

探索微前端的三种技术方案_第4张图片

  1. iframe
  2. multi-page
  3. qiankun

一、iframe

 

直接在需要插入的地方,使用iframe将所需要呈现的业务页面url插入即可,src的路径可以是当前项目也可以是其他项目的。这种方式在PC端的效果还算中肯,移动端呈现的效果不佳。iframe的优点是简单易用,没有什么学习成本,缺点也显而易见,seo不友好、适配的空间有局限性、可能发生多次请求产生性能问题。

二、multi-page

vue-cli搭建的项目举例,在multi-page模式下构建应用,每个page应该有一个对应的JavaScript入口文件,我们把每一个需要松耦合的项目当成一个子项目即新创建一个page,并且新增一个相应的入口文件page.main.js
vue.config.js文件下做如下配置:

pages: { // 配置多页面入口
    index: { // 入口一
        entry: 'src/main.js',
        template: 'public/index.html'
    },
    demo: {  // 入口二
        entry: 'src/demo/demo.main.js',
        template: 'public/demo.html'
    }
}

如上面代码所示,vue项目中配置了两个pageindexdemo,对应的有两个main.js入口文件,当然public里也有对应的两个html文件,如图:

探索微前端的三种技术方案_第5张图片

  • 使用multi-page的方式实现微前端的思路是,将一个vue项目分化成若干不同的子项目,每个项目作为一个单页应用
  • 这种方案也没有什么学习成本,只需要根据实际情况创建不同的page
  • 在实际开发中,总体的架构方面是固定的,各个团队在不同的page下独立开发不同的模块,互不影响,团队之间唯一的交集可能是在修改vue.config.js文件的相关配置产生


demo地址

以上是示例效果,存在两个page页面homedemo,从home跳转到demo,也可以从demo跳转回home。根据自己的场景,可以使用window.location.href或者window.location.replace在子应用间做跳转。

三、qiankun

qiankun是蚂蚁金服技术团队基于single-spa开发的微前端框架,整体比较方便,提供基座应用,只需将各个微应用注册在基座后,便可以实现微前端架构,基座应用的运行不影响微应用,可以独立开发部署。

主应用

在主应用(基座)中注册微应用并启动:

import { registerMicroApps, start } from 'qiankun';

registerMicroApps([
  {
    name: 'reactApp',
    entry: '//localhost:3000',
    container: '#container',
    activeRule: '/app-react',
  },
  {
    name: 'vueApp',
    entry: '//localhost:8080',
    container: '#container',
    activeRule: '/app-vue',
  },
  {
    name: 'angularApp',
    entry: '//localhost:4200',
    container: '#container',
    activeRule: '/app-angular',
  },
]);
// 启动 qiankun
start();

微应用

微应用不需要额外安装任何其他依赖即可接入qiankun主应用,但是要在微应用中做以下两项操作:

1. 导出相应的生命周期钩子

微应用需要在自己的入口 js(如main.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(, 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);
}
2. 配置微应用的打包工具
const packageName = require('./package.json').name;


module.exports = {
  output: {
    library: `${packageName}-[name]`,
    libraryTarget: 'umd',
    jsonpFunction: `webpackJsonp_${packageName}`,
  },
};


demo地址

以上是示例效果,两个微应用存在于主应用中,主应用就像是一个宿主环境的浏览器,每个微应用内部的切换就像iframe一样自然

参考资料

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