乾坤实战教程

2023-11-10

一、什么是微前端架构

微前端不是单纯的前端框架或者工具,而是一套架构体系,这个概念最早在2016年底被提出,可以参考在Google上搜索Micro-Frontends,排名靠前的http://micro-frontends.org的博客文章,提出了早起的微前端模型。

前短短是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将单页面前端应用由单一应用转变为把多个小型前端应用聚合唯一的应用。各个前端应用还可以独立开发、独立部署。

微前端架构旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员。团队的增多、变迁,从一个普通应用变成一个巨星应用,随之而来的应用不可维护的问题。这类问题在企业级Web应用中尤其常见。

微前端的实现意味着对前端应用的拆分。拆分应用的目的并不只是为了在结构上好看,它还可以提升开发效率。比如10万行代码拆分成10个项目,每个项目1万行代码,要独立维护每个项目就会容易得多。而我们只需要实现应用的自治,及实现应用的独立运行和部署,就可以在某种程度上实现为前端架构的目的。

二、使用场景

微前端帮助开发者解决了实际的问题,但是对于每个业务来说,是否适合使用为前端,以及是否正确的使用微前端,还是需要遵循以下一些原则:

  1. 微前端最佳的使用场景是一些B段的管理系统,即能兼容机成立时系统,也可以将新的系统集成进来,并且不影响原先的交互体系。
  2. 整体的微前端不仅仅是只将系统集成进来,而是整个微前端体系的完善,这其中就包括:
    • 基座应用和微应用的自动部署能力
    • 微应用的配置管理能力
    • 本地开发调试能力
    • 线上监控和统计能力等等

只有将真个能力体系搭建完善,才能说是整个微前端体系流程的完善。

除此之外,他也有一系列的缺点:

  • 应用的拆分基础依赖与基础设施的构建,一旦大量应用依赖于统一基础设施,那么维护变成了一个挑战。
  • 拆分的力度越小,便意外着架构变得复杂、维护成本变高
  • 技术栈一旦多样化,便意味着技术栈混乱

当发现使用为前端反而是效率变低,简单的变更复杂那说明为前端并不适用。

三、如何实现微前端

从技术实践上,为前端架构可以采用以下几种方式进行:

  1. 路由分发式。通过http服务器的反向代理功能,将请求路由到对应的应用上。
  2. 前端微服务器化,在不同的框架之上设计通信和加载机制,以在一个页面内加载对应的应用。
  3. 微应用。通过软件工程的方式,再部署构建环境中,把多个独立的应用组合成一个单独应用。
  4. 微件化。开发一个新的构建系统,将部分业务功能构建成一个独立的chunk代码,使用时只需要远程加载即可。
  5. 前端容器化。将iframe作为容器来容纳其他前端应用。
  6. 应用组件化。借助于Web components技术,来构建跨框架的前端应用。

实施的方式虽然多,但都是依据场景而采用。在有些场景下,可能没有合适的方式;在有些场景下,则可以同时使用多中方式来实现。

四、架构模式

中心化:基座模式

在这种模式的为前端架构中,基座承担了微前端应用的基础与技术核心。基座模式,是由一个主应用和一系列业务自应用构成的系统,并由这个主应用来管理其他子应用,包括从子应用的生命周期管理到应用间的通信机制。

基座模式中的主应用,类似于API Gateway的概念,他作为系统的统一入口,负责将对应的请求指向对应的服务。子应用,则是负责各个子模块的业务实现,其架构如图所示。

在这里插入图片描述

这个主应用,既可以只带有单纯的基座功能,也可以带有业务功能。它所处理的业务功能指的是核心部分的业务功能,如:

● 用户的登录、注册管理。
● 系统的统一鉴权管理。
● 导航菜单管理。
● 路由管理。
● 数据管理。
● 通信代理。
● ……

作为应用的基础核心,它还需要:

● 维护应用注册表。在应用注册表上表明系统有多少个服务、能否找到对应的应用等。
● 管理其他子应用。如在何时加载应用、何时卸载应用等。

要实现这种模式的微前端架构,只需要设计好对应的应用加载机制即可,因此在实施的时候也比较方便。

中心化微前端架构的典型代表是:乾坤

去中心化:自组织模式

去中心化自组织模式指的是,系统内部各子系统之间能自行按照某种规则形成一定的结构或功能。采用这种模式可以使系统内的各种前端应用,都各自拥有一个小型的基座管理功能,也相当于每个应用都可以是基座。

在采用基座模式时,用户要想访问A应用需要先加载主应用,然后才能加载A应用。采用自组织模式时,用户想要访问A应用则只访问A应用,不需要加载主应用,这也因此使它拥有了更高的自主性。

不过多数时候,我们并不需要自组织模式的微前端架构,因为它设计起来复杂、拥有大量的重复代码。

去中心化的微前端设计有一个很好的实现,就是在2020年出现的基础webpack的模块联邦。

五、微前端架构方案

Single-Spa:最早的微前端框架(2018年),兼容多种前端技术栈,核心只做路由劫持和应用加载。
○ 本身没有处理样式隔离、JavaScript 执行隔离
Qiankun:诞生于2019年,基于 Single-Spa,阿里系开源微前端框架。对vite支持不是很好
○ single-spa + sandbox + import-html-entry
○ 本身解决了样式隔离、JavaScript 执行隔离
○ 接入简单
● 2020年 webpack5 模块联邦
● 2020 年 EMP 基于 Module Federation(模块联邦),接入成本低,解决第三方依赖包的问题
Icestark:阿里飞冰微前端框架,兼容多种前端技术栈。

六、qiankun快速入门

qiankun 介绍

● qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。
● 使用简单
○ 技术栈无关,任意技术栈的应用均可 使用/接入,不论是 React/Vue/Angular/JQuery 还是其他等框架。
○ HTML Entry 接入方式,让你接入微应用像使用 iframe 一样简单。
● 功能完备:几乎包含所有构建微前端系统时所需要的基本能力。
○ 样式隔离,确保微应用之间样式互相不干扰。
○ JS 沙箱,确保微应用之间 全局变量/事件 不冲突。
○ 资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。
○ umi 插件,提供了 @umijs/plugin-qiankun 供 umi 应用一键切换成微前端架构系统。
● 生产可用:qiankun 孵化自蚂蚁金融科技基于微前端架构的云产品统一接入平台,在经过一批线上应用的充分检验及打磨后,我们将其微前端内核抽取出来并开源,希望能同时帮助社区有类似需求的系统更方便的构建自己的微前端系统,同时也希望通过社区的帮助将 qiankun 打磨的更加成熟完善。目前 qiankun 已在蚂蚁内部服务了超过 200+ 线上应用,在易用性及完备性上,绝对是值得信赖的。
● 架构思想:中心化基座模式的微前端典型代表,由一个主应用和一系列业务子应用构成的系统,并由这个主应用来管理其他子应用,包括从子应用的生命周期管理到应用间的通信机制。

主应用

1、创建项目

首先安装vue-vli命令行工具:npm install -g @vue/cli

创建main、app1、app2三个项目:

  • vue create main(选择vue3带router版本)
  • 然后复制main代码到app1app2

2、主项目配置(main)

在主项目中,添加div容器。

app.vue:

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/app1">app1</router-link> |
      <router-link to="/app2">app2</router-link>
    </div>
    <router-view/>
    <div id="container"></div> <!--子应用容器-->
  </div>
</template>

注册子应用:

main.ts:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import { registerMicroApps,setDefaultMountApp , start } from "qiankun";

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

registerMicroApps([
  {
    name: 'app1',
    entry: '//localhost:8082',
    container: '#container',
    activeRule: '/app1',
  },
  {
    name: 'app2',
    entry: '//localhost:8083',
    container: '#container',
    activeRule: '/app2',
  },
]);

setDefaultMountApp("app1")
// 启动 qiankun
start();

3、子项目配置(app1)

a. 创建-src/public-path.js

if (window.__POWERED_BY_QIANKUN__) {
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

b.修改-main.js

import './public-path';
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
import routes from './router';
import store from './store';

Vue.config.productionTip = false;

let router = null;
let instance = null;
function render(props = {}) {
  const { container } = props;
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/app1/' : '/',
    mode: 'history',
    routes,
  });

  instance = new Vue({
    router,
    store,
    render: (h) => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}

// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

export async function bootstrap() {
  console.log('[app1] vue app bootstraped');
}
export async function mount(props) {
  console.log('[app1] props from main framework', props);
  render(props);
}
export async function unmount() {
  console.log('[app1] unmount');
  instance.$destroy();
  instance.$el.innerHTML = '';
  instance = null;
  router = null;
}

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

c.打包配置-vue.config.js

const { name } = require('./package');
module.exports = {
  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*',//支持跨域
    },
    port:8082
  },
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      libraryTarget: 'umd', // 把微应用打包成 umd 库格式
      jsonpFunction: `webpackJsonp_${name}`,
    },
  },
};

app2如同app1一样配置。注意启动端口配置成:8083。

4、启动

分别启动main、app1、app2三个项目;然后打开主应用地址。

请添加图片描述

5、部署

主应用和微应用部署到同一个服务器(同一个 IP 和端口)

a、主应用-main.js

registerMicroApps([
  {
    name: 'app1',
    entry: '/child/app1',
    container: '#container',
    activeRule: '/app1',
  },
  {
    name: 'app2',
    entry: '/child/app2',
    container: '#container',
    activeRule: '/app2',
  },
]);

b、子应用publicPath+base

vue.config.js

const { name } = require('./package');
module.exports = {
  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
    port:8082
  },
  publicPath:"/child/app1/", // 主要调整的这里
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      libraryTarget: 'umd',
      jsonpFunction: `webpackJsonp_${name}`,
    },
  },
};

router/index.js

const router = new VueRouter({
  mode: 'history',
  base: window.__POWERED_BY_QIANKUN__ ? '/app1/' : '/child/app1/',
  routes
})

app2同样配置。

main、app1、app2执行npm run build打包;将app1和app2中打包生成的dist目录,复制到main/dist/child中,并且重命名为app1和app2,调整后目录结构如图:

在这里插入图片描述
本地建立http服务,http-server dist,这时就能正常访问;

还需要解决刷新http://127.0.0.1:8081/app1时的404问题。

源码

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

乾坤实战教程 的相关文章

  • 禁用内容安全策略

    当我开发网站时 我经常想看看特定功能在网站上的外观如何 所以我会使用 chrome 开发者工具并经常运行一些 javascript 脚本 我经常发现一些脚本由于内容安全策略 CSP 而无法运行的问题 我完全理解该策略是为了防止跨站点脚本攻击
  • 我如何在 AngularJS 中监听点击并按住的情况?

    我制作了一个时间计数器 您可以通过单击按钮来增加或减少时间 然而 我希望当我单击并按住按钮时 时间的价值会不断攀升 所以目前如果你看到我的Plunkr http plnkr co edit BxX9x5zYFMXVqt5JsN1F p pr
  • VBA / HTML / jQuery 选择自动完成 - 在列表中选择

    我正在尝试使用 Excel 中的 VBA 在网站的列表中选择一个值 这不是一个 正常列表 该网站使用 jQuery 选择自动完成 如下所示 example http davidwalsh name demo jquery chosen ph
  • Node js 使用中间件重定向进行过多重定向

    在我的 Node js 应用程序 我使用的是express 4 x 中 我想检查用户是否已登录 如果用户未登录 我想重定向到我的登录页面 然后我在中间件中这样做 服务器 js app use function req res next if
  • 如何仅在 NextJS 站点构建期间使用 getInitialProps?

    当使用 NextJS 构建静态站点时 我想要getInitialProps方法仅在构建步骤期间触发 而不是在客户端上触发 在构建步骤中 NextJS 运行getInitialProps 方法 https nextjs org docs fe
  • Ember.js 处理 View 事件后转换到路由

    Setup 我有一个 Ember 应用程序 支持使用 Imgur API 上传图像 我已经有一个工作路线和模板来处理任何 Imgur ID 但我想在上传新图像后转换到此路线 使用返回的 Imgur ID 这是该应用程序的相关部分 http
  • Node.js - console.log 不显示数组中的项目,而是显示 [Object]

    我在注销对象内数组的内容时遇到问题 实际的物体看起来像这样 var stuff accepted item1 item2 rejected response Foo envelope from The sender to new item1
  • 是否有任何非轮询方式来检测 DOM 元素的大小或位置何时发生变化?

    很长一段时间以来 我一直在寻找一种方法来检测 DOM 元素的大小或位置何时发生变化 这可能是因为窗口调整了大小 或者因为向该元素添加了新的子元素 或者因为在该元素周围添加了新元素 或者因为 CSS 规则已更改 或者因为用户更改了浏览器的字体
  • 使用 JS 合并具有相同值的相邻 HTML 表格单元格

    我已经为此苦苦挣扎了一段时间 我有一个根据一些 JSON 数据自动生成的表 该数据可能会有所不同 我想合并第一列中具有相同值的相邻单元格 例如此表中的 鱼 和 鸟 table tr td fish td td salmon td tr tr
  • 将 javascript 整数转换为字节数组并返回

    function intFromBytes x var val 0 for var i 0 i lt x length i val x i if i lt x length 1 val val lt lt 8 return val func
  • Twitter 嵌入时间轴小部件

    我继续下载http platform twitter com widgets js http platform twitter com widgets js And the http platform twitter com embed t
  • Chartjs刻度标签位置

    尝试让 Y 轴刻度标签看起来像image https i stack imgur com XgoxX png 位于秤顶部且不旋转 缩放选项当前如下所示 scales yAxes id temp scaleLabel display true
  • 如果数字小于 10,则显示前导零 [重复]

    这个问题在这里已经有答案了 可能的重复 JavaScript 相当于 printf string format https stackoverflow com questions 610406 javascript equivalent t
  • JavaScript onresize 事件多次触发

    我在尝试仅在触发 onresize 事件时运行一次函数时遇到一些麻烦 我已经看过这个问题DOM onresize 事件 https stackoverflow com questions 1500312 javascript onresiz
  • 无法在前端使用 JavaScript Fetch API 将文件上传到 FastAPI 后端

    我正在尝试弄清楚如何将图像发送到我的 API 并验证生成的token那是在header的请求 到目前为止 这就是我所处的位置 app post endreProfilbilde async def endreProfilbilde requ
  • 如何在 Google 地图 V3 中创建编号地图标记?

    我正在制作一张上面有多个标记的地图 这些标记使用自定义图标 但我还想在顶部添加数字 我已经了解了如何使用旧版本的 API 来实现这一点 我怎样才能在V3中做到这一点 注意 当您将鼠标悬停在标记上时 标题 属性会创建一个工具提示 但我希望即使
  • 单击引导分页链接时调用 jquery 函数

    我想在单击引导分页链接时调用 jquery 函数 假设我想从第1页遍历到第2页 应该调用一个jquery函数 我正在使用以下代码 但它不起作用 ul pagination on click li function alert page ch
  • 在 Javascript 中减少/分组数组

    基于this https stackoverflow com a 40774906 3254598例如 我想以稍微不同的方式按对象进行分组 结果应该如下 key audi items make audi model r8 year 2012
  • KeyboardAvoidingView - 隐藏键盘时重置高度

    我正在使用 React NativeKeyboardAvoidingView设置我的高度View当显示键盘时 但是当我关闭应用程序中的键盘时 视图的高度不会变回原来的值
  • 用于 C# XNA 的 Javascript(或类似)游戏脚本

    最近我准备用 XNA C 开发另一个游戏 上次我在 XNA C 中开发游戏时 遇到了必须向游戏中添加地图和可自定义数据的问题 每次我想添加新内容或更改游戏角色的某些值或其他内容时 我都必须重建整个游戏或其他内容 这可能需要相当长的时间 有没

随机推荐

  • Vue.js子级向父级传递数据

    组件之间的数据的传递 子传父 注意 html对大小写不敏感 事件名字最好用 隔开或全部小写 步骤 1 在父组件中在子组件上添加事件 自定义 监听 代表的含意 事件分两类 浏览器自带的事件 click mouseover mousedown
  • 11-2_Qt 5.9 C++开发指南_QSqlQueryModel的使用(QSqlQueryModel 只能作为只读数据源使用,不可以编辑数据)

    文章目录 1 QSqlQueryModel 功能概述 2 使用 QSqlQueryModel 实现数据查询 2 1 实例功能 2 2 可视化UI设计 2 3 主窗口类定义 去除自动生成的槽函数 2 4 打开数据库 2 5 记录移动 1 QS
  • java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Integer

    因为BigDecimal不能强制转换成 String类型 要用toString 作为中间桥梁转换 同理 Object BigDecimal转换成int doulbe long 也是一样的 List
  • 灰灰-判断是否存在重复数

    给定一个整数数组 判断是否存在重复元素 如果任何值在数组中出现至少两次 函数返回 true 如果数组中每个元素都不相同 则返回 false 示例 1 输入 1 2 3 1 输出 true 示例 2 输入 1 2 3 4 输出 false 示
  • QT笔记——QTableWidget 之 指定某列排序

    指定某列共有2种方式 1 重写 bool QTableWidgetItem operator lt const QTableWidgetItem other const 2 点击表头进行排序 connect ui tableWidget g
  • Python配置第三方库最全教程

    学Python最让人头疼的莫过于去配置一大堆杂乱的第三方库 而下载第三方库时报错也能让你崩溃 今天 我整理了一份全的教程 最常用的办法下载第三方库 在终端中执行 pip install 第三方库名称 大部分人一般不会报错 但偏偏我去安装最基
  • fbmem驱动框架分析

    文章目录 fbmem驱动框架分析 1 与misc驱动框架类比 1 1 my first cdev的记录 1 2 关于misc驱动框架的总结 2 fbmem驱动框架 2 1提供注册函数 2 2 操作函数分析 2 2 1 open函数分析 op
  • google analytics 添加跟踪代码

    google analytics添加跟踪代码实现统计分析 其代码添加方式共有三种 1 gtag js 基础代码
  • 个人网站搭建 04——WebHooks 实现远程项目的自动部署

    环境说明 Github 或 Gitee 维护的网站代码 支持 Webhooks 由于 Github 访问速度受限 易出现超时问题 我使用 Gitee 部署代码 Linux 公网服务器 阿里云 腾讯云 华为云等 服务器操作环境为 CentOS
  • Windows环境下 Redis RDB持久化无法生成dump.rdb文件

    Windows环境下 Redis RDB持久化无法生成dump rdb文件 问题 删除dump rdb文件 配置redis windows conf的SNAPSHOTTING 设置在60秒内进行了5次操作 即写入rdb文件中进行持久化保存
  • spring cloud 版本错Cannot resolve org.springframework.cloud:spring-cloud-starter-openfeign:unknown

    Cannot resolve org springframework cloud spring cloud starter openfeign unknown 说明 创建spring cloud项目后依赖错误 原因 版本错误 如下图 有些博
  • 怎么进入项目后台服务器,项目部署并常驻在服务器后台

    前言 上一次文章是自己的博客项目正式上线 这次分享 怎么让自己写好的项目常驻与服务器后台 在这之前 先了解一下服务器部署项目的一些环境依赖问题 服务器部署项目时 你的项目用到了什么环境 就要在服务器上安装相应的环境依赖 一般常要安装的就是M
  • 二进制颜色代码大全(含图)

    二进制颜色代码大全 可供大家开发时参考 FFFFFF DDDDDD AAAAAA 888888 666666 444444 000000 FFB7DD FF88C2 FF44AA FF0088 C10066 A20055 8C0044 FF
  • 如何证明凸函数的局部极小值为全局极小值

    最近上系统分析这门课的时候 老师提到了这个概念 当我们能够确定凸函数的局部最小值 这个最小值即为全局极小值 但并未给出证明 这里记录一下 主要用的还是凸函数的定义 凸函数区间任意位置的函数值小于两区间端点函数值之和
  • c#客户端Kafka的使用方法

    简介 Apache Kafka是一个分布式流处理平台 最初由LinkedIn开发 现在是Apache软件基金会的顶级项目之一 Kafka能够处理大规模的实时数据流 支持高可靠性 高可扩展性 低延迟和高吞吐量 它主要用于构建实时数据管道和流式
  • Pycharm debug 的使用

    Debug 作用的理解 若整个代码编写没有错误 且执行体没有设置断点时 Debug同正常运行模式 直接得到最终结果 当某一行代码设置断点后 在Debug模式下 代码会运行断点之前的所有程序 在断点处暂停 并在 变量窗口 可以查看所有主程序当
  • C#学习笔记:RadioButton控件与CheckBox控件的用法

    一 用途 1 RadioButton控件 单选按钮 当与其他单选按钮成对出现时 允许用户从一组选项中选择单个选项 也就是说 当同一个容器中 Form Panel GroupBox PictureBox等 存在两个以上的单选按钮时 只能有一个
  • C#对象和类--习题(1)

    1 一个景区根据游人的年龄收取不同价格的门票 请编写游人类 根据年龄段决定能够购买门票价格并输出 class XiTi string name int age void Xiti1 for 死循环 类似的while true Console
  • 代理模式——静态代理(贴近业务)

    静态代理概念 所谓静态也就是在程序运行前就已经存在代理类的字节码文件 代理类和委托类的关系在运行前就确定了 通常用于对原有业务逻辑的扩充 举例理解 以结婚为例 当事人只需要处理自己的主要事儿即可 比如典礼 洞房 其他的杂事儿可以交给代理公司
  • 乾坤实战教程

    一 什么是微前端架构 微前端不是单纯的前端框架或者工具 而是一套架构体系 这个概念最早在2016年底被提出 可以参考在Google上搜索Micro Frontends 排名靠前的http micro frontends org的博客文章 提