乐趣区

关于前端:浅入深出的微前端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#/

作者:京东批发 陈艳春

起源:京东云开发者社区 转载请注明起源

退出移动版