浅入深出的微前端MicroApp

这篇具有很好参考价值的文章主要介绍了浅入深出的微前端MicroApp。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

本文是由最近做的一个项目有感而发,因为之前做了一些技术栈的统一,为了用ant Design的pro-table,PC统一使用react,但是我们有一些老的项目是vue的,本次新页面较多,老页面的改动较少,除此之外老项目想换菜单,因此我们想借助本次机会用react开发,经过了几番思考,发现本次很适合用微前端来完成本次需求,最终决定用react搭建一个基座(主应用),将原来的vue项目接入到基座,这样我们不仅实现了新页面react开发,而且老项目也能和新项目融合一起。

微前端的概念

什么是微前端?微前端是借鉴了微服务的架构理念,它既可以将多个项目融合为一,又可以减少项目之间的耦合,提升项目扩展性,相比一整块的前端仓库,微前端架构下的前端仓库倾向于更小更灵活。有一个基座应用(主应用),来管理各个子应用的加载和卸载。所以微前端不是指具体的库,不是指具体的框架,不是指具体的工具,而是一种理想与架构模式。微前端的核心三大原则:独立运行、独立部署、独立开发。

何时使用微前端

(1)一个非常庞大的项目,越来越大,后续难以维护。

(2)在一些大厂,经常会有跨部门和跨团队协作开发项目,这样会导致团队效率降低和沟通成本加大,这时我们可以使用微前端,每个团队或者每个部门单独维护自己的项目,我们只需要一个主项目来把分散的子项目汇集到一起即可。

(3)一个非常老旧的项目,开发效率低,但是一时半会又不能全部重构,这时我们就可以新创建一个新技术新项目的基座,把老项目的页面接入到新项目里面,后面新需求都在新项目里面开发就好,不用再动老项目。

(4)想独立部署每一个单页面应用。

(5)改善初始化加载时间,延迟加载代码。

(6)基于多页的子应用缺乏管理,规范/标准不统一,无法统一控制视觉呈现、共享的功能和依赖。造成重复工作。

如何创建微前端基座

一、微前端框架选型

(1)现有框架

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

2.qiankun 是一款基于 single-spa 封装的微前端框架。

  1. MicroApp 京东出品,一款基于WebComponent的思想,轻量、高效、功能强大的微前端框架。

我们本次项目使用的是umi+react+ts的技术栈,其实比较适合用qiankun,qiankun继承了umi框架,但是这个框架配置起来比较麻烦,其次就是MicroApp 是京东旗下的。

(2)****MicroApp 优势

1、使用起来成本最低,将所有的封装到一个类WebComponent组件中,从而实现在主应用基座中嵌入一行代码即可渲染一个微前端应用。

2、不需要像 single-spa 和 qiankun 一样要求子应用修改渲染逻辑并暴露出方法,也不需要修改webpack配置,是目前市面上接入微前端成本最低的方案。

3、提供了 js沙箱、样式隔离、元素隔离、预加载、数据通信、静态资源补全等一系列完善的功能。

4、没有任何依赖,这赋予它小巧的体积和更高的扩展性。

5、为了保证各个业务之间独立开发、独立部署的能力,micro-app做了诸多兼容,在任何技术框架中都可以正常运行。

(3)****MicroApp 概念图

二、场景演示

以后台管理系统为例

最外层是基座,基座是微前端应用集成的一个重要平台。同时也肩负着管理公共资源、依赖、规范的责任。主要有以下职责:

(1)子应用集成,给子应用提供渲染容器

(2)权限管理

(3)会话管理

(4)路由、菜单管理

(5)主题管理

(6)共享依赖

(7)多语言管理(最重要的一点)等

content里面可以任意放不同技术的子应用,我们只需要开发一个主应用(主应用也可以自由选择语言,目前支持react、vue、vite、angular、next.js、nuxt.js),将一些分散的应用接进来,主应用还可以通过控制权限,让不同的账号看到的菜单不一样,即看到不同系统的页面,通过同一个地址访问到不同的子应用。

三、搭建微前端基座

以react基座为例

1、创建项目

(1)首先确保本地node版本>= 14(推荐用nvm来管理 node 版本,windows 下推荐用nvm-windows)

(2)通过官网提供命令可以快速创建一个基于 UMI 的项目作为主应用也就是我们所谓的基座

(3)安装依赖

npm i @micro-zoe/micro-app --save

package.json文件里面dependencies里面会多一行代码,看到下面代码恭喜你,项目已经具备micro-app接入能力了。

"@micro-zoe/micro-app": "^1.0.0-alpha.7"

(4)在入口引入我们的micro-app

首先在根目录下创建一个global.tsx文件

import microApp from '@micro-zoe/micro-app'

microApp.start()

(5)在主应用引入子应用

a. 分配一个子应用路由

  {
    path: '/yp',
    name: 'yp',
    linkHidden: true,
    linkDisable: true,
    breadcrumbClose: true,
    component: '@/pages/yp-app',
  }


b. 子应用的文件

在pages文件下创建一个yp-app(子应用的文件)

// name(必传):应用名称 // url(必传):应用地址,会被自动补全为http://localhost:3000/index.html

import React from 'react';
import config from '@/config';

// /** @jsxRuntime classic */
// /** @jsx jsxCustomEvent */
// import jsxCustomEvent from '@micro-zoe/micro-app/polyfill/jsx-custom-event';

export default (): React.ReactElement => {
  
  // 子应用点击了面包屑的回到首页
  const onDispathChild = (e: any) => {
    const { isBackHome } = e.detail.data;
    if (isBackHome) window.location.href = '/';
  };

  return (
    <>
      <micro-app name="yp" url={config?.yp} onDataChange={onDispathChild} />
    </>
  );
};

说明:onDataChange方法是子应用和主应用的信息通讯方法。micro-app 在 window 下面挂载了一个全局的对象,我们只需要去触发它提供的方法,完成主子之间的通信即可,不管是交互逻辑还是数据传递逻辑,就都通了。

c.主应用成功引入子应用(子应用是VUE项目)

到目前为止如果我们的项目不存在跨域问题,子应用就已成功接入了主应用,此时我们就可以看到如下图:

左侧是主应用,中间模块是子应用,里面包含子应用的整个模块菜单和列表,考虑到菜单统一放到主应用(基座)方便管理,我们需要把子应用的页面的菜单以及一些 不必要的东西删除,然后我们把子项目一些公共样式公共布局等都统一调整下即可,最终我们会得到一个主应用+子应用页面最终页面,恭喜你到这里你就成功接入了第一个子应用,第二个应用。。。。等应用按照同样步骤。

接入完成不代表你子应用里面所有的模块都能用了,此时我们还需要检查导出和导入的接口是获取域名里面的还是单独定义的,如果获取域名里面的前缀,此时你的导入导出不能正常使用,我们需要重新给导入导出单独定义,比如在子应用创建一个单独的host.js文件,引用根据环境区分到处的域名前缀。

2、路由跳转

通过主应用的菜单跳转到对应子应用的路由

//config.ts
let config = {
  yp: 'https://xxx.xxx.com:7000/gw',//本地环境子应用的路由前缀
};

const isEnvPro = process.env.NODE_ENV === 'production';

if (isEnvPro) {
  config = {
    yp: 'https://xxx.xxx.com/gw',//预发环境环境子应用的路由前缀
  };
}

export default config;
//以上是config.ts文件的全部-----end


//菜单点击事件里面的内容

history.push('/yp'); //切换到子应用

setTimeout(() => {
    microApp.router.push({
      name: 'yp',//和子应用的name要保持一致,为了匹配到对应子应用的路由
      path: `${config.yp}${item.url}`,
    }); //跳转子应用的路由,其中config是上面的配置文件,根据不同的环境取对应环境的子应用,item是当前点击的菜单路径信息
}, 500);

这里解释下为啥要用setTimeout,首先通过history.push('/yp')切换到子应用,防止切换过去之后短时间内找不到子应用的路由,所以加个延迟能够准确的跳转到子应用对应的路由。

3、设置跨域

(1)如果你仅仅本地跨域的话可以给子应用设置,在webpack-dev-server的headers中设置跨域支持:

devServer: {
  headers: {
    'Access-Control-Allow-Origin': '*',
  }
},

这个有相对应的文档,我们根据子应用的语言设置不同的跨域信息。

(2)如果你是接口跨域。

那么你就需要找后端设置允许我们前端跨域的代码了,Java为例:

  @Override
    public void init(FilterConfig filterConfig) {
        this.origins = Lists.newArrayList("http://localhost:8088",
            "https://xx.51epei.com",
            "https://xx.yunxiu.com",
            "https://dev.51epei.com:8088",
            "https://xx.51epei.com:7000");
    }

这个是基础配置,我们还可以改成同域名下的所有都允许跨域,最好不要设置成'*',这样很不安全。

4、代理配置

如果你遇见主应用本地访问不到子应用本地,访问的一直是预发或者线上,这时候你需要首先考虑你的代理是否配对,比如我的一个子项目,如图所示:

proxy: (() => {
  return {
    //  本地访问预发
    '/avoid': {
      target: 'https://pai.51epei.com',
      changeOrigin: true,
      bypass: (req) => {
        if(req.headers.accept.indexOf('html') !== -1 ) {
          return '/index'
        }
      },
    }
  }
})()

最初本地代理是路由里面包含'/'就代理到预发上,正常单独访问子应用的链接,可以正常访问本地代理预发的接口,但是放到主应用里面就不可以了,最后给代理改成了整个项目公共部分/avoid,解决了此问题,不一定你的项目是因为这个,但是我觉得可以从代理入手查找问题。

5、数据通讯

micro-app提供了一套灵活的数据通信机制,方便基座应用和子应用之间的数据传输。

正常情况下,基座应用和子应用之间的通信是绑定的,基座应用只能向指定的子应用发送数据,子应用只能向基座发送数据,这种方式可以有效的避免数据污染,防止多个子应用之间相互影响。

同时我们也提供了全局通信,方便跨应用之间的数据通信。

子应用获取来自基座应用的数据,以及基座应用向子应用发送数据,基座应用获取来自子应用的数据,全局数据通讯,具体的我这里都不细说了,文档里都有详细介绍,详细参考https://zeroing.jd.com/docs.html#/zh-cn/data

总结

通过上述介绍我们可以知道,采用微前端架构的好处就是,将原本运行已久、没有任何关联的几个应用融合为一个应用,或者将很多个小型单个应用融合为一个完整的应用,可以减少项目之间的耦合,提升项目扩展性。micro-app借鉴了WebComponent的思想,通过CustomElement结合自定义的ShadowDom,将微前端封装成一个类WebComponent组件,从而实现微前端的组件化渲染。并且由于自定义ShadowDom的隔离特性,也不需要修改webpack配置,是目前市面上接入微前端成本最低的方案,因此也得到广大程序员的青睐。

虽说微前端已经是一个非常成熟的领域了,我们使用微前端目的就是为了降本提效,但是在现在的这个开源大环境,我们使用哪种框架,或者自己实现微前端都可以,个人觉得应该考虑如果当前的项目接入微服务之后,变得维护成本更高,那就要考虑是否适合微前端了,我们不能为了用而用,微前端并不是适合所有的场景,遇到问题尝试着去考虑多种方案方案解决。

参考资料:micro-app官网: https://zeroing.jd.com/docs.html#/

作者:京东零售 陈艳春

来源:京东云开发者社区 转载请注明来源文章来源地址https://www.toymoban.com/news/detail-710073.html

到了这里,关于浅入深出的微前端MicroApp的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 让小程序动起来-轮播图的两种方式--【浅入深出系列003】

    微信目录集链接在此: 详细解析黑马微信小程序视频–【思维导图知识范围】 难度★✰✰✰✰ 不会导入/打开小程序的看这里:参考 让别人的小程序长成自己的样子-更换window上下颜色–【浅入深出系列001】 用免费公开视频,卷飞培训班哈人!打死不报班,赚钱靠狠干! 只

    2024年02月16日
    浏览(48)
  • Docker由浅入深(一)

    容器化技术介绍 介绍容器化之前,我们得先知道,为什么会出现容器化,容器化之前都经历了什么 物理机时代 部署非常慢 成功很高 浪费资源 难于扩展与迁移 受制于硬件 虚拟化时代 在同一个物理机上安装多个虚拟机,每个虚拟机安装操作系统和应用, 虚拟机之间物理资源

    2024年02月03日
    浏览(55)
  • 由浅入深了解HashMap源码

           由经典面试题引入,讲解一下HashMap的底层数据结构?这个面试题你当然可以只答,HashMap底层的数据结构是由(数组+链表+红黑树)实现的,但是显然面试官不太满意这个答案,毕竟这里有一个坑需要你去填,那就是在回答HashMap的底层数据结构时需要考虑JDK的版本,因

    2023年04月13日
    浏览(46)
  • 由浅入深Netty代码调优

    序列化,反序列化主要用在消息正文的转换上 序列化时,需要将 Java 对象变为要传输的数据(可以是 byte[],或 json 等,最终都需要变成 byte[]) 反序列化时,需要将传入的正文数据还原成 Java 对象,便于处理 目前的代码仅支持 Java 自带的序列化,反序列化机制,核心代码如

    2024年02月05日
    浏览(46)
  • 【个人笔记】由浅入深分析 ClickHouse

    项目中不少地方使用到ClickHouse,就对它做了一个相对深入一点的了解和研究。并对各种知识点及整理过程中的一些理解心得进行了汇总并分享出来,希望对其他同学能有帮助。 本文主要讲解ClickHouse的特点、读写过程、存储形式、索引、引擎、物化视图等特性。 适合 入门和

    2024年01月20日
    浏览(47)
  • React - redux 使用(由浅入深)

    中文文档: http://www.redux.org.cn/ 英文文档: https://redux.js.org/ Github: https://github.com/reactjs/redux 可直接参照 目录十 进行使用 react-redux redux 是一个专门用于做状态管理的JS库(不是react插件库)。 它可以用在 react, angular, vue 等项目中, 但基本与 react 配合使用。 作用: 集中式管理 re

    2024年02月07日
    浏览(54)
  • 由浅入深理解C#中的事件

    本文较长,给大家提供了目录,可以直接看自己感兴趣的部分。 前面介绍了C#中的委托,事件的很多部分都与委托类似。实际上,事件就像是专门用于某种特殊用途的简单委托,事件包含了一个私有的委托,如下图所示: 有关事件的私有委托需要了解的重要事项如下: 1、事

    2024年02月03日
    浏览(44)
  • 【由浅入深学习MySQL】之索引进阶

    本系列为:MySQL数据库详解,为千锋资深教学老师独家创作 致力于为大家讲解清晰MySQL数据库相关知识点,含有丰富的代码案例及讲解。如果感觉对大家有帮助的话,可以【关注】持续追更~ 文末有本文重点总结,技术类问题,也欢迎大家和我们沟通交流! 从今天开始本系列

    2024年02月05日
    浏览(45)
  • 手拉手Vue组件由浅入深

    组件 (Component) 是 Vue.js 最强大的功能之一,它是html、css、js等的一个聚合体,封装性和隔离性非常强。 组件化开发:     1、将一个具备完整功能的项目的一部分分割多处使用     2、加快项目的进度     3、可以进行项目的复用 组件注册分为:全局注册和局部注册 目录

    2024年01月18日
    浏览(46)
  • 由浅入深介绍 Python Websocket 编程

    1.1 websocket 协议简介 Websocket协议是对http的改进,可以实现client 与 server之间的双向通信; websocket连接一旦建立就始终保持,直到client或server 中断连接,弥补了http无法保持长连接的不足,方便了客户端应用与服务器之间实时通信。 适用场景 html页面实时更新, 客户端的html页面

    2024年02月03日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包