2024年微前端实战(qiankun+umi+antd)

前言

接上文,因为公司新项目涉及到多个系统,且系统之间有相互共用的模块与页面,为了降低开发成本,就搭建了这套系统。 本文档涵盖了从环境准备到前端开发,主子项目部署、打包配置,nginx 配置等一系列关键步骤。其中 nginx 相关配置的模块我认为是最重要的模块。需要反复摩擦几次。

在开始下文前,我默认你大概了解了:umi、qiankun、antd、nginx 的使用,并对微前端的架构模式和使用场景有所了解。

不知道?那你还不去看看相关的资料?

项目介绍

目前该项目使用微前端架构方案,一共包含 1 个主项目,4 个子项目。其中 3 个项目为业务层,1 个项目为基建层。

本文配置的子项目可以直接嵌套在主项目中,子项目也可以单独脱离出来单独使用(授权登录的话需要自己做一些额外的配置)。

项目名称 说明
main 整套系统的框架,外壳
app1 a 系统
app2 b 系统
app3 c 系统
app4 公共能力

开发流程

这里介绍一下,各个仓库的起始开发流程和规范。

第一步:初始化开发环境

  1. 通过 git 把仓库代码 clone 到本地,从对应的版本分支创建一条自己的 feature 分支。
  2. 执行 pnpm i, 等待依赖安装完之后,执行 pnpm run start 进行本地开发。
  3. 注入登录模块,开发环境下可以通过该配置绕过登录授权调试(重要
js 复制代码
import slave from '@nicecode/slave';

export const qiankun = {
  /**

* 子应用的生命周期,每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
   */
  async mount() {
    // 注入子应用登录跳转
    slave.init({
      // jumpToLogin: false,     // 是否跳转登录页,默认打开,如果开发调试可以关闭跳转
      jumpUrl: `https://base.nicecode.com/material/login`,
    });
  },
};

链接上的 会告诉用户跳转到哪个页面去授权登录,但是页面上要有 from 或者是 to 字段。用来授权回跳,理论上跳转的优先级是:属性 to > 属性 from > 链接上的 to > 链接上的 from 一般授权成功跳转回来的链接上会带上 token 字段,例如: j710328466.github.io/nicenote?to...

第二步:代码推送

  1. 执行 git add .,暂存所有待推送文件。
  2. 执行 git commit -m "${commitMsg}" commitMsg 可以为当前的修改内容,遵循 commit 提交规范,例如:feat(package): 修改配置包属性 在这个阶段会执行相对应的 lint fix 和 prettier fix,不要跳过!
  3. 待 lint 校验通过之后,再执行 git push 提交代码到远程。
  4. 在 gitlab 提交 mr 到对应分支,并且指定相关人员 CR。

第三步:触发镜像配置 CI

进入 gitlab 的流水线触发即可,再次打开服务器地址就能看到最新的页面了!

项目配置

微前端架构的好处就是整体是一个可插拔的结构,按需加载引用子项目

4.1 主应用

第一步:在 app.ts 中注册子应用

按需接入相应的应用,这里的 APP_ENV 用来区分本地环境和生产环境的加载路由,可以通过在 umijs 的 define 属性定义,再通过 npm 命令传递,详细可以参考 umijs 手册

js 复制代码
export const qiankun = {
  apps: [
    {
      name: 'app1',
      entry:
        APP_ENV === 'production'
          ? `//${hostname}:30068/app1/`
          : '//localhost:30068/',
      props: {},
      singular: false,
      credentials: true,
    },
    {
      name: 'app2',
      entry:
        APP_ENV === 'production'
          ? `//${hostname}:30088/app2/`
          : '//localhost:30088/',
      singular: false,
      credentials: true,
    },
    {
      name: 'app3',
      entry:
        APP_ENV === 'production'
          ? `//${hostname}:30078/app3/`
          : '//localhost:30078/',
      singular: false,
      credentials: true,
    },
    {
      name: 'app4',
      entry:
        APP_ENV === 'production'
          ? `//${hostname}:30098/app4/`
          : '//localhost:30098/',
      singular: false,
      credentials: true,
    },
  ],
};

要注意这里的两个属性:

  1. singular:子应用是否预加载,最好设置为 false,防止其它子应用卸载的时候,控制台会报错。
  2. credentials:这个设置了的话,请求的子应用就会默认带上 cookie 校验,这样 nginx 配置会略微有些麻烦,不过不打紧。

第二步:在主应用中的 umirc.ts 中注册 4 个子应用

这个没啥好说的,就是重置了子应用的路由,映射到所有的微应用。microApp 不要错了,对应注册的子应用名称。

js 复制代码
{
  ...
  routes: [
    {
        name: '应用1',
        path: '/app1/*',
        microApp: 'app1'
    },
    {
        name: '应用2',
        path: '/app2/*',
        microApp: 'app2'
    },
    {
        name: '应用3',
        path: '/app3/*',
        microApp: 'app3'
    },
    {
        name: '应用4',
        path: '/app4/*',
        microApp: 'app4'
    }
  ]
  ...
}

4.2 子应用

子应用相对配置简单一点,只需要修改 umijs.ts 文件的一个属性就行:

js 复制代码
{
  ...
  qiankun: {
    slave: {}
  }
  ...
}

项目 nginx 配置

主应用

这里我只贴出重要的部分,具体负载均衡和接口映射啥的,需要和后端协调进行修改:

js 复制代码
{
  ...
      server {
          listen       30058;

          location / {
              if ($request_method = 'OPTIONS') {
                  add_header 'Access-Control-Allow-Origin' '$http_origin' always;
                  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                  add_header 'Access-Control-Allow-Credentials' 'true';
                  add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorizationept';
                  add_header 'Access-Control-Max-Age' 1728000;
                  return 204;
              }
              add_header 'Access-Control-Allow-Origin' '$http_origin' always;
              add_header 'Access-Control-Allow-Credentials' 'true';

              root   /web/main;
                  try_files $uri $uri/ /index.html;
              index  index.html index.htm;
          }

          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
              root   html;
          }
      }
  ...
}

子应用

子应用就是比主应用多了个路由的映射,和 proxy 的设置,其它都差不多。

js 复制代码
{
  ...
  server {
      listen       30078;

      location /app1 {
          // proxy_set_header Host $host;
          // proxy_set_header X-Real-IP $remote_addr;
          // proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

          if ($request_method = 'OPTIONS') {
              add_header 'Access-Control-Allow-Origin' '$http_origin' always;
              add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
              add_header 'Access-Control-Allow-Credentials' 'true';
              add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorizationept';
              add_header 'Access-Control-Max-Age' 1728000;
              return 204;
          }
          add_header 'Access-Control-Allow-Origin' '$http_origin' always;
          add_header 'Access-Control-Allow-Credentials' 'true';

          try_files $uri $uri/ /app1/index.html;
          alias  /web/app1;
          index  index.html index.htm;
      }

      error_page   500 502 503 504  /50x.html;
      location = /50x.html {
          root   html;
      }
  }
  ...
}

小结

整个架构从开始环境搭建,开发到部署上线。历时大概 3 个月左右,中间碰到了挺多问题,其中关于 nginx 配置的问题是最多的,基本上就是在恶补还不知道的 nginx 知识。

其次再是相关的公司服务端 CI 部署相关的内容,因为运维方面涉及到 ducker 和 k8s,因为项目的特殊性,也不是用传统的 Jenkins 或者其它 ci 方案,并且是由同一套配置组件化来管理 nginx 配置和部署方案,所以很多时候的项目推进比较麻烦。

简单点说就是,我不是很懂运维那套架构体系,运维说做不了或者没时间...

链接

个人博客

nicecode

相关推荐
qq_3901617714 分钟前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test44 分钟前
js下载excel示例demo
前端·javascript·excel
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事1 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶1 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo1 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
理想不理想v1 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
知孤云出岫1 小时前
web 渗透学习指南——初学者防入狱篇
前端·网络安全·渗透·web
贩卖纯净水.1 小时前
Chrome调试工具(查看CSS属性)
前端·chrome
栈老师不回家2 小时前
Vue 计算属性和监听器
前端·javascript·vue.js