2022 你还不会微前端吗 (上) — 从巨石应用到微应用(一)

简介: 2022 你还不会微前端吗 (上) — 从巨石应用到微应用

image.png


前言

微前端系列分为 上/下 两篇,本文为 上篇 主要还是了解微前端的由来、概念、作用等,以及基于已有的微前端框架进行实践,并了解微前端的核心功能所在,而在下篇 2022 你还不会微前端吗 (下) — 揭秘微前端核心原理 中主要就是通过自定义实现一个微前端框架来加深理解。


微前端是什么?

微前端 是一种类似于 微服务 的概念,因此要想更好的了解微前端,就必须先了解一下微服务。

微服务

微服务架构 是将一个庞大的业务系统按照业务模块拆分成 若干个独立的子系统,每个子系统都是一个独立的应用,它是一种将应用构建成一系列按 业务领域 划分模块的、小的自治服务的软件架构方式,倡导将 复杂的单体应用 拆分成 若干个功能单一、松偶合的服务,目的是降低开发难度、增强扩展性、便于敏捷开发,及持续集成与交付活动。

image.png

与微服务相对的另一个概念是传统的 单体式应用程序( Monolithic application ),单体式应用内部包含了 所有需要的服务,且各个服务功能模块具有 强耦合性(相互依赖),导致难以进行拆分和扩容。

image.png

简单来说,单体式应用程序 其实就是一台服务器处理了需要所有的功能,微服务 就是将功能按照业务模块划分成了不同的独立服务,各个微服务间通过 HTTP 协议进行通信,通过注册中心观测微服务状态。

微服务 概念主要存在于后端开发,但这个概念是不是和你听说过的 微前端 很像了。

微前端

随着大前端的快速发展 和 SPA 的大规模应用,也带来了新的问题,而这些问题都催化出了 微前端 的概念:

  • 项目功能不断增多、体积不断增大(巨石应用),导致打包时间成正比例增长,是否能保证更好的 项目扩展
  • 前端技术更新太快,一个项目历经一两年也许就需要进行项目升级,甚至是切换技术栈,但仍需要老项目的代码,是否能进行 新老版本的兼容
  • 团队技术栈不一,又需要保证同一项目的开发,是否能保证不同团队的 独立开发
  • SPA 项目的任何变动都需执行完整的打包、部署,是否能保证不同内容 独立部署

image.png

微前端 是一种类似于 微服务 的架构,是一种由独立交付的 多个前端应用 组成整体的架构风格,将前端应用分解成一些更小、更简单的能够 独立开发、测试、部署 的应用,而对外表现仍是 单个内聚的产品

微前端框架

微前端框架的核心

一个微前端框架至少要保证如下的核心功能:

  • 技术栈无关
  • 主框架不限制接入子应用的技术栈,微应用具备完全自主权
  • 独立开发、独立部署
  • 微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新
  • 增量升级
  • 在面对各种复杂场景时,通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略
  • 独立运行时
  • 每个微应用之间状态隔离,运行时状态不共享

single-spa

single-spa 是一个将多个单页面应用聚合为一个整体应用的 JavaScript 微前端框架。

核心原理

基座 (主) 应用 中注册所有 App 的路由,single-spa 保存各子应用的路由映射关系,充当微前端控制器 Controler,当对应的 URL 变换时,除了匹配 基座应用 本身的路由外,还会匹配 子应用 路由并加载渲染子应用。

子应用会经过如下过程

  • 下载 (loaded)
  • 初始化 (initialized)
  • 挂载 (mounted)
  • 卸载 (unmounted)

single-spa 还会通过 生命周期 为这些过程提供对应的 钩子函数

qiankun

qiankun 是一个基于 single-spa微前端 实现库,目的是提供更简单、无痛的构建一个生产可用微前端架构系统。

包括在 single-spa 文档中也有推荐使用 qiankun

image.png

single-spa 实践

创建子应用

Vue3 子应用

为了快速的创建应用,这里通过 vue create vue3-micro-app 来快速创建技术栈为 Vue3子应用

以下在子应用中的处理方式可用 single-spa-vue 来简化

页面效果如下

image.png

子应用入口文件

为了子应用既可以独立运行,也可以在基座应用中运行,需要在子应用入口文件进行一些修改,具体如下:

  • 将原本的初始化内容封装在自定义的 render 函数中,目的是可以在不同的环境执行初始化操作
  • 若当前在基座应用中进行渲染,则其页面内容对应的挂载容器需要指定为基座容器中对应的 DOM 节点
  • window.singleVue3 不存在时意味着是子应用独立运行,此时直接按照原本的初始化方式进行即可,即直接调用 render() 函数
  • 子应用必须导出 bootstrap、mount、unmount 等生命周期函数,且其返回值类型要为 fullfilled 状态的 Promise,否则后续操作不会执行
  • 定义 instance 变量存储实例对象,方便在当前子应用在基座应用中被切换时可以执行真正的卸载子应用
// main.ts
import { createApp } from 'vue'
import type { App as AppType } from 'vue'
import App from './App.vue'
import router from './router'
let instance: AppType
function render(container?: string) {
    instance = createApp(App)
    instance.use(router).mount(container || '#micro-vue-app')
}
// 当 window.singleVue3 不存在时,意味着是子应用单独运行
if (!window.singleVue3) {
    render();
}
// 子应用必须导出 以下生命周期 bootstrap、mount、unmount
export const bootstrap = () => {
    return Promise.resolve()
};
export const mount = (props: any) => {
    render(props.container);
    return Promise.resolve()
};
export const unmount = () => {
    instance.unmount();
    return Promise.resolve()
};
复制代码

为什么要将 x.mount('#app') 换成 x.mount('#micro-vue-app') ?

如果你明白 子应用基座应用 中的渲染方式就不难理解了,因为当前这个子应用的挂载容器的 id="app" 而基座应用中的默认挂载容器也是 id="app",这显然会导致冲突,初始化渲染时会渲染基座应用本身,但是当你切换到 vue3 的子应用时,就会发现当前子应用的内容整个覆盖了基座应用的内容,因为此时子应用在进行挂挂载的时候,会把已经渲染 基座应用 的容器再一次作为 子应用 的容器进行渲染,于是内容就会被完全替换成子应用的内容。

基座应用被子应用替换效果如下:

image.png

路由配置

路由模式为 hash 模式,默认路由配置:

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]
const router = createRouter({
  history: createWebHashHistory(),
  routes
})
export default router
复制代码

打包配置

vue.config.js 下必须将打包后的输出格式指定为 umd 格式:

module.exports = {
  configureWebpack: {
    output: {
      library: 'singleVue3',
      libraryTarget: 'umd',
      globalObject: 'window',
    },
    devServer: {
      port: 5000,
    },
  },
}
复制代码

React 子应用

类似的,这里通过 npx create-react-app react-micro-app 来快速创建技术栈为 React子应用

以下在子应用中的处理方式可用 single-spa-react 来简化

页面效果如下

image.png

子应用入口文件

此部分核心内容和上述的 vue3 子应用一致,不在额外说明,入口文件代码如下:

// index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
let root = null
function render(props = {}) {
  const container = document.getElementById(
    props.container ? props.container.slice(1) : 'root',
  )
  if(!container) return
  root = ReactDOM.createRoot(container)
  root.render(
    <React.StrictMode>
      <App {...props} />
    </React.StrictMode>,
  )
}
// 当 window.singleReact 不存在时,意味着是子应用单独运行
if (!window.singleReact) {
  render()
}
// 子应用必须导出 以下生命周期 bootstrap、mount、unmount
export const bootstrap = () => {
  return Promise.resolve()
}
export const mount = (props) => {
  render(props)
  return Promise.resolve()
}
export const unmount = () => {
  root.unmount()
  return Promise.resolve()


目录
相关文章
|
18天前
|
移动开发 缓存 前端开发
深入理解前端路由:原理、实现与应用
本书《深入理解前端路由:原理、实现与应用》全面解析了前端路由的核心概念、工作原理及其实现方法,结合实际案例探讨了其在现代Web应用中的广泛应用,适合前端开发者和相关技术人员阅读。
|
28天前
|
前端开发 项目管理
Gitflow分支策略及其在前端工程化中的应用
Gitflow 分支策略也并非适用于所有项目。对于一些小型或简单的前端项目,可能会显得过于复杂。在实际应用中,需要根据项目的具体情况和团队的需求进行适当调整和优化。
|
24天前
|
自然语言处理 前端开发 JavaScript
深入理解前端中的 “this” 指针:从基础概念到复杂应用
本文全面解析前端开发中“this”指针的运用,从基本概念入手,逐步探讨其在不同场景下的表现与应用技巧,帮助开发者深入理解并灵活掌握“this”的使用。
|
24天前
|
存储 前端开发 JavaScript
前端中对象的深度应用与最佳实践
前端对象应用涉及在网页开发中使用JavaScript等技术创建和操作对象,以实现动态交互效果。通过定义属性和方法,对象可以封装数据和功能,提升代码的组织性和复用性,是现代Web开发的核心技术之一。
|
28天前
|
前端开发
结合具体案例分析Gitflow分支策略在大型前端项目中的应用优势
通过这个具体案例可以看出,Gitflow 分支策略在大型前端项目中能够提供有条不紊的开发环境,保障项目的稳定性和持续发展。
|
27天前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
40 5
|
1月前
|
前端开发 开发者
本文将深入探讨 BEM 的概念、原理以及其在前端开发中的应用
BEM(Block-Element-Modifier)是一种前端开发中的命名规范和架构方法,旨在提高代码的可维护性和复用性。通过将界面拆分为独立的模块,BEM 提供了一套清晰的命名规则,增强了代码的结构化和模块化设计,促进了团队协作。本文深入探讨了 BEM 的概念、原理及其在前端开发中的应用,分析了其优势与局限性,为开发者提供了宝贵的参考。
48 8
|
25天前
|
JavaScript 前端开发 测试技术
构建高效可维护的前端应用
构建高效可维护的前端应用
|
25天前
|
编解码 监控 JavaScript
打造高效前端应用
打造高效前端应用
34 1
|
28天前
|
前端开发 JavaScript 开发者
使用React和Redux构建高效的前端应用
使用React和Redux构建高效的前端应用
33 1