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()


目录
相关文章
|
4天前
|
前端开发 JavaScript Java
Java语言在Web前端开发中的技术应用
Java语言在Web前端开发中的技术应用
|
11天前
|
JavaScript 前端开发 NoSQL
构建基于Node.js的全栈应用:从前端到后端的完整指南
【5月更文挑战第24天】本文是关于使用Node.js构建全栈应用的指南,涵盖前端(React或Vue)、后端(Node.js + Express)和数据库(MongoDB)的选型与实现。文章介绍了项目结构、前端组件化开发、后端API接口编写、前后端联调及部署上线的注意事项,帮助读者掌握全栈开发流程。
|
12天前
|
JavaScript 前端开发
TypeScript 学习笔记(六):TypeScript 与前端框架的结合应用
笔记,进一步提升 TypeScript 编程技能。
17 1
|
15天前
|
前端开发 Java Go
从前端到后端:构建现代化Web应用的技术演进
本文探讨了从前端到后端的技术演进,介绍了前端、后端以及多种编程语言,如Java、Python、C、PHP和Go,以及数据库在构建现代化Web应用中的应用。通过深入剖析各个技术领域的发展和应用,读者将对构建高效、可扩展、安全的Web应用有更深入的理解。
|
18天前
|
前端开发 Java Go
从前端到后端:构建现代化Web应用的技术实践
本文将介绍如何通过前端和后端技术相结合,构建现代化Web应用的技术实践。我们将探讨前端开发、后端架构以及多种编程语言(如Java、Python、C、PHP、Go)在构建高效、可扩展的Web应用中的应用。
|
18天前
|
前端开发 JavaScript 测试技术
第八章(应用场景篇) 中大型项目的解构:从单体应用到微前端
第八章(应用场景篇) 中大型项目的解构:从单体应用到微前端
|
19天前
|
Web App开发 前端开发 JavaScript
构建跨浏览器兼容的前端应用:技术实践与挑战
【5月更文挑战第16天】构建跨浏览器兼容的前端应用是应对浏览器差异和多样性的挑战。使用现代框架(如React、Vue)能自动转换代码,编写可移植的Web标准代码,结合浏览器兼容性测试工具和Polyfill解决旧浏览器支持问题。关注浏览器更新,应对性能、API差异和样式问题,采用渐进增强、条件判断和CSS Reset策略确保应用在各种浏览器上运行良好。
|
19天前
|
前端开发 JavaScript Java
浅谈企业级前端应用中的组件概念和具体的应用
浅谈企业级前端应用中的组件概念和具体的应用
21 1
|
20天前
|
JSON 前端开发 JavaScript
快照测试在前端自动化测试中的应用
在前端自动化测试中,快照测试常用于检验组件渲染与布局。
|
20天前
|
缓存 移动开发 前端开发
【专栏:HTML与CSS前端技术趋势篇】HTML与CSS在PWA(Progressive Web Apps)中的应用
【4月更文挑战第30天】PWA(Progressive Web Apps)结合现代Web技术,提供接近原生应用的体验。HTML在PWA中构建页面结构和内容,响应式设计、语义化标签、Manifest文件和离线页面的创建都离不开HTML。CSS则用于定制主题样式、实现动画效果、响应式布局和管理字体图标。两者协同工作,保证PWA在不同设备和网络环境下的快速、可靠和一致性体验。随着前端技术进步,HTML与CSS在PWA中的应用将更广泛。