MicroApp初探

news2024/11/26 3:31:53

微前端

微前端是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立运行、独立开发、独立部署。微前端架构与框架无关,每个微应用都可以使用不同的框架。

MicroApp

MicroApp借鉴了WebComponent的思想,通过CustomElement结合自定义的ShadowDom,将微前端封装成一个类WebComponent组件,从而实现微前端的组件化渲染。并且由于自定义ShadowDom的隔离特性,micro-app不需要像single-spa和qiankun一样要求子应用修改渲染逻辑并暴露出方法,也不需要修改webpack配置,是目前市面上接入微前端成本最低的方案。 – 《MicroApp》

本篇文章为 MicroApp 的使用初探,您可以选择通过 官方demo 进行对框架全面了解。

快速开始

主应用 - react

源码:github

架构

1. 项目准备

1. 创建项目

  1. 创建主应用项目:npx create-react-app react18
  2. 创建子应用项目-react:npx create-react-app react18
  3. 创建子应用项目-vue3:vue create vue3

2. 安装相关依赖

  1. 【主应用】安装微前端框架: npm i @micro-zoe/micro-app --save
  2. 【主应用】安装路由依赖:npm i react-router-dom
  3. 【子应用-react】安装路由依赖:npm i react-router-dom
  4. 【子应用-react】安装跨域解决支持依赖:npm install react-app-rewired customize-cra --save-dev
  5. 【子应用-vue3】安装路由依赖:npm install vue-router

2. 搭建相关路由系统

  1. 【主应用】路由系统

    // router/index.js
    import { lazy, Suspense } from 'react'
    import { createBrowserRouter } from 'react-router-dom'
    import Home from '../pages/home'
    
    const React18 = lazy(() =>
      import(/* webpackChunkName: "react18" */ '../pages/React18')
    )
    const Vue3 = lazy(() => import(/* webpackChunkName: "vue3" */ '../pages/Vue3'))
    
    const router = createBrowserRouter([
      {
        path: '/',
        element: <Home />,
        errorElement: <div>404</div>,
        children: [
          {
            path: 'react18',
            element: (
              <Suspense fallback={<div>loading...</div>}>
                <React18 />
              </Suspense>
            ),
          },
          {
            path: 'vue3',
            element: (
              <Suspense fallback={<div>loading...</div>}>
                <Vue3 />
              </Suspense>
            ),
          },
        ],
      },
    ])
    
    export default router
    
  2. 【主应用】路由系统相关组件

    // react18
    const React18 = () => {
      return (
        <div>
          <micro-app
            name="react18"
            url="http://localhost:3311/"
            baseroute="/react18"
          />
        </div>
      )
    }
    
    export default React18
    
    // vue3
    const Vue3 = () => {
      return (
        <div>
          <micro-app name="vue3" url="http://localhost:3312/" baseroute="/vue3" />
        </div>
      )
    }
    
    export default Vue3
    
  3. 【子应用-react】路由系统

    // router/index.js
    import { createBrowserRouter } from 'react-router-dom'
    import { lazy, Suspense } from 'react'
    import Home from '../pages/home'
    
    const About = lazy(() =>
      import(/* webpackChunkName: "about" */ '../pages/about')
    )
    const Detail = lazy(() =>
      import(/* webpackChunkName: "detail" */ '../pages/detail')
    )
    
    const router = createBrowserRouter(
      [
        {
          path: '/',
          element: <Home />,
          // 这里放置自己的路由即可
          children: [
            {
              path: '/about',
              element: (
                <Suspense fallback={<div>loading</div>}>
                  <About />
                </Suspense>
              ),
            },
            {
              path: 'detail/:id',
              element: (
                <Suspense fallback={<div>loading</div>}>
                  <Detail />
                </Suspense>
              ),
            },
          ],
        },
      ],
      // 注意此处为微前端侵入性修改
      {
        basename: window.__MICRO_APP_BASE_ROUTE__ || '/',
      }
    )
    
    export default router
    
  4. 【子应用-vue3】路由系统

    import { createRouter, createWebHistory } from 'vue-router'
    
    const router = createRouter({
      // 注意此处为微前端侵入性修改
      history: createWebHistory(
        window.__MICRO_APP_BASE_ROUTE__ || process.env.BASE_URL
      ),
      routes: [
        {
          path: '/detail',
          name: 'detail',
          component: () => import('../pages/Detail.vue'),
        },
        {
          path: '/about',
          name: 'about',
          component: () => import('../pages/AboutView.vue'),
        },
      ],
    })
    
    export default router
    

3. 引入微前端框架

  1. 【主应用】入口文件引入框架

    // index.js
    import microApp from '@micro-zoe/micro-app'
    
    microApp.start()
    

4. 子应用跨域问题处理

  1. 【子应用-react】修改package.json

    "scripts": {
      "start": "react-app-rewired start",
      "build": "react-app-rewired build",
      "test": "react-app-rewired test",
      "eject": "react-scripts eject"
    },
    
  2. 【子应用-react】根目录下添加 config-overrides.js

    const { overrideDevServer } = require('customize-cra')
    module.exports = {
      devServer: overrideDevServer((config) => {
        return {
          ...config,
          headers: {
            'Access-Control-Allow-Origin': '*',
          },
        }
      }),
    }
    
  3. 【子应用-vue】根目录vue.config.js中添加配置

    const { defineConfig } = require('@vue/cli-service')
    
    module.exports = defineConfig({
      // ...
      devServer: {
        port: 3312,
        headers: {
          'Access-Control-Allow-Origin': '*',
        },
      },
    })
    

5. 子应用设置publicPath

  1. 【子应用-react】src目录下创建名称为public-path.js的文件,并添加如下内容

    // __MICRO_APP_ENVIRONMENT__和__MICRO_APP_PUBLIC_PATH__是由micro-app注入的全局变量
    if (window.__MICRO_APP_ENVIRONMENT__) {
      // eslint-disable-next-line
      __webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__
    }
    
  2. 【子应用-react】入口文件的最顶部引入public-path.js

    // entry
    import './public-path'
    
  3. 【子应用-vue】src目录下创建名称为public-path.js的文件,并添加 同上述react子应用中相同内容

  4. 【子应用-vue】入口文件的最顶部引入public-path.js

🏷提示:

到这里已经完成一个微前端的基本搭建工作,展示效果如下:

demo 效果

整个接入过程非常简单,侵入性的操作总结有:

  • 主应用
    • microApp.start()
    • 添加微应用的容器组件
    • 添加路由指向这个容器组件
  • 微应用
    • 修改 public-path
    • 添加跨域访问
    • 自动切换路由的 basename

数据通信

父传子

  1. 【主应用】修改路由

    // router/index.js
    import { lazy, Suspense } from 'react'
    import { createBrowserRouter } from 'react-router-dom'
    import Home from '../pages/home'
    
    const React18 = lazy(() =>
      import(/* webpackChunkName: "react18" */ '../pages/React18')
    )
    const Vue3 = lazy(() => import(/* webpackChunkName: "vue3" */ '../pages/Vue3'))
    
    const router = createBrowserRouter([
      {
        path: '/*',
        element: <Home />,
        errorElement: <div>404</div>,
        children: [
          {
            path: 'react18/*',
            element: (
              <Suspense fallback={<div>loading</div>}>
                <React18 />
              </Suspense>
            ),
          },
          {
            path: 'vue3/*',
            element: (
              <Suspense fallback={<div>loading</div>}>
                <Vue3 />
              </Suspense>
            ),
          },
        ],
      },
    ])
    
    export default router
    
  2. 【主应用】页面组件添加以下内容

    // React18
    const location = useLocation()
    
    useEffect(() => {
      // 第一个参数为子应用名称
      microApp.setData('react18', {
        path: location.pathname.replace('/react18', ''),
      })
    }, [location.pathname])
    
    // 其他页面组件将相应第一个参数和路由进行修改即可
    
  3. 【子应用-react】在首页添加监听事件并重定向路由

    const navigate = useNavigate()
    
      useEffect(() => {
        function dataListener(data) {
          if (data.path) {
            navigate(data.path)
          }
        }
        if (window.__MICRO_APP_ENVIRONMENT__) {
          window.microApp.addDataListener(dataListener)
        }
        return () => {
          if (window.__MICRO_APP_ENVIRONMENT__) {
            // 解绑监听函数
            window.microApp.removeDataListener(dataListener)
            // 清空当前子应用的所有绑定函数(全局数据函数除外)
            window.microApp.clearDataListener()
          }
        }
      }, [])
    
  4. 【子应用-vue】在首页添加监听事件并重定向路由

    mounted() {
      const router = useRouter()
      function dataListener(data) {
        if (data.path) {
          router.push(data.path)
        }
      }
      if (window.__MICRO_APP_ENVIRONMENT__) {
        window.microApp.addDataListener(dataListener)
      }
    },
    unmounted() {
      if (window.__MICRO_APP_ENVIRONMENT__) {
        // 解绑监听函数
        window.microApp.removeDataListener()
        // 清空当前子应用的所有绑定函数(全局数据函数除外)
        window.microApp.clearDataListener()
      }
    },
    

子传父

  1. 【子应用-react】监听路由改变

    // home/index.js
    const location = useLocation()
    
    useEffect(() => {
      if (window.microApp) {
        window.microApp.dispatch({
          path: location.pathname,
        })
      }
    }, [location.pathname])
    
  2. 【主应用】获取数据并做出响应

    // home/index.js
    const [selectedKeys, setSelectedKeys] = useState([])
    
    useEffect(() => {
      function dataListener(data) {
        setSelectedKeys([`/react18${data.path}`])
      }
    
      microApp.addDataListener('react18', dataListener)
    
      return () => {
        // 解绑监听my-app子应用的函数
        microApp.removeDataListener('react18', dataListener)
        // 清空所有监听appName子应用的函数
        microApp.clearDataListener('react18')
      }
    }, [])
    

    子应用发送数据等操作同理,这里就不做演示了,可直接看源码~

完成效果如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/345879.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VMware虚拟机安装部署CentOS7+Moba远程连接+克隆(步骤)

使用VMware部署centos7操作系统 1. 打开VMware点击“创建新的虚拟机” 2.按提示逐步选择 选择NAT模式&#xff08;只要电脑能联网&#xff0c;虚拟机就能联网&#xff09; 磁盘存为单个文件 点击“使用iso映像文件”&#xff0c;选择已经下载好的镜像文件。 &#xff08;虚…

火爆全网的ChatGPT对话数据可视化,分析数据可视化的应用和发展

ChatGPT为一款由OpenAI开发的人工智能聊天软件。2022年11月30日上映。截至2023年1月底&#xff0c;其月活跃用户超过1亿&#xff0c;是有史以来增长最快的消费应用。今年AIGC&#xff08;是指利用人工智能技术来生成内容&#xff09;频繁出圈&#xff0c;先是一个基于diffusion…

【转载】Visual Studio 下载进度很慢甚至不动怎么办?

原文链接&#xff1a;https://zhuanlan.zhihu.com/p/566305175 现在越来越多的人投身到计算机行业成为了一名码农&#xff0c;对于一个合格的码农来说能熟练的使用Visual Studio&#xff0c;Visual Studio code,idea等是很重要的&#xff0c;也有很多人在软件下载方面就遇到了难…

python【os模块文件读写操作】超详细

一、os 模块是什么&#xff1a;os 模块是python 标准库中整理文件和目录最为常用的模块&#xff0c;该模块提供了非常丰富的方法用来处理文档和目录二、认识文件路径分隔符&#xff1a;- 路径表示"\"在windows操作系统中表示区分文件的存储路径层级关系比如&#xff…

2022爱分析 · DataOps厂商全景报告 | 爱分析报告

报告编委 李喆 爱分析合伙人&首席分析师 廖耘加 爱分析分析师 目录 1. 研究范围定义 2. 市场洞察 3. 厂商全景地图 4. 市场分析与厂商评估 5. 入选厂商列表 1. 研究范围定义 研究范围 在后疫情时代&#xff0c;以数据分析为代表的数据消费场景日益丰富&…

Linux 用户讲解

目录 Linux 用户介绍 Linux用户类型 UID 用户组ID Linux 用户相关命令 id 查看用户信息 useradd 创建新的用户账户 groupadd 创建新的用户组 usermod 修改用户的属性 passwd 修改用户的密码、过期时间等 userdel 删除用户 通过文件的方法新建、编辑用户 /etc/p…

【操作系统】磁盘IO常见性能指标和分析工具实战

1.磁盘读写常见的指标 &#xff08;1&#xff09;IOPS&#xff08;Input/Output Operations per Second&#xff09; 指每秒能处理的I/O个数&#xff0c;表示块存储处理读写&#xff08;输出/输入&#xff09;的能力&#xff0c;单位为次&#xff0c;有顺序IOPS和随机IOPS比如…

设计模式第五讲-装饰器模式和代理模式详解

一. 装饰器模式 1. 背景 在现实生活中&#xff0c;常常需要对现有产品增加新的功能或美化其外观&#xff0c;如房子装修、相片加相框等。在软件开发过程中&#xff0c;有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下&#xff0c;可以…

软件测试工程师需要掌握哪些技能呢?

在谈到软件测试工程师时&#xff0c;许多人还是会想到那些重复使用软件并试图在频繁的操作中发现 BUG的人&#xff0c;也就是人们常说的按照测试规范和测试案例来测试软件&#xff0c;检查软件是否有错误&#xff0c;判断软件是否稳定。但这是一个很老派和错误的观点。 由于以…

持续测试:企业的4项策略

对于旅游业和酒店服务来说&#xff0c;节假日无疑是最繁忙的时期。2022年的节假日历经了多重变化&#xff0c;恶劣的天气以及不可抗力因素影响了许多出行计划&#xff0c;也影响了航空公司的运营。为了确保一个顺利和成功的假期&#xff0c;开发团队必须为意想不到的事情做好准…

openvino yolov5/ssd 实时推流目标检测在html上显示

安装ffmepg并添加到环境变量中&#xff0c;流媒体使用m7s 运行效果 SSD&#xff1a;检测在10ms左右&#xff0c;yolov5在100ms左右 app.py #!/usr/local/bin/python3 # encodin: utf-8import subprocess import threading import time import cv2 import osfrom OpenVinoYoloV…

遥感概念理解(更新中)

目录看一幅波长与光对应的图1、波段2、波段组合3、多波段数据的三种存储方式4、全色5、彩色6、 多光谱7、高光谱看一幅波长与光对应的图 1、波段 波段又称为波谱段或波谱带&#xff0c;在遥感技术中&#xff0c;通常把电磁波谱划分为大大小小的段落&#xff0c;大的成为波段区…

2023年数据安全的下一步是什么?

IT 预算和收入增长领域是每个年度开始时的首要考虑因素&#xff0c;在当前的世界经济状况下更是如此。 IT 部门和数据团队正在寻找确定优先级、维护和构建安全措施的最佳方法&#xff0c;同时又具有成本效益。 这是一个棘手的平衡点&#xff0c;但却是一个重要的平衡点&#…

java ssm自行车在线租赁系统idea

当前自行车在社会上广泛使用,但自行车的短距离仍旧不能完全满足广大用户的需求。自行车在线租赁系统可以为用户提供租赁用车等功能,拥有较好的用户体验.能实时在线租赁提供更加快捷方便的租车方式,解决了常见自行车在线租赁系统较为局限的自行车归还功能。 通过使用本系统&…

C语言学习笔记(九):文件的操作

C文件的知识 什么是文件 操作系统把各种设备都统一作为文件来处理。例如&#xff0c;终端键盘是输入文件&#xff0c;显示屏和打印机是输出文件。 文件一般指存储在外部介质上数据的集合。操作系统是以文件为单位对数据进行管理的 输入输出是数据传送的过程&#xff0c;数据…

【LeetCode】1124. 表现良好的最长时间段

1124. 表现良好的最长时间段 题目描述 给你一份工作时间表 hours&#xff0c;上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候&#xff0c;那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」&#xff0c;意味在这段时间…

多线程下载工具axel的安装和使用

多线程下载工具axel的安装和使用 Axel是一个轻量级下载程序&#xff0c;它和其他加速器一样&#xff0c;对同一个文件建立多个连接&#xff0c;每个连接下载单独的文件片段以更快地完成下载。 Axel 支持 HTTP、HTTPS、FTP 和 FTPS 协议。它也可以使用多个镜像站点下载单个文件…

Springboot 使用插件 自动生成Mock单元测试 Squaretest

缘起 很多公司对分支单测覆盖率会有一定的要求&#xff0c;比如 单测覆盖率要达到 60% 或者 80%才可以发布。 有时候工期相对紧张&#xff0c;就优先开发功能&#xff0c;测试功能&#xff0c;然后再去补单元测试。 但是编写单元测试又比较浪费时间&#xff0c;有没有能够很大…

Spirng 痛苦源码学习(四)——AOP老大哥

文章目录前言一、探究AOP开始&#xff0c;判断导入的相关组件1.跟踪源码流程二、对切面中的增强方法进行增强1.源码的过程三、使用aop的目标类生成代理对象总结前言 Spring的两大特性&#xff1a;IOC&#xff1b;AOP。本篇仅以跟完Spring AOP相关源码为依据写的总结 一、探究A…

MySQL入门篇-MySQL高级窗口函数简介

备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊MySQL高级窗口函数 窗口函数在复杂查询以及数据仓库中应用得比较频繁 与sql打交道比较多的技术人员都需要掌握 如需要scott用户下建表及录入数据语句&#xff0c;可参考:scott建表及录入数据sql脚本 分析函数有3个基本组成…