Skip to content

yicheny/micro-app-demo

Repository files navigation

[TOC]

微服务Demo--基座应用

文档

docs目录,里面放了微服务的介绍,以及实践中的各种踩坑记录,尤其是踩坑记录,很有价值,我个人强烈推荐参照,以节省自己的踩坑时间。

子项目介绍

子项目见packages目录:

  1. child-app1 使用cra创建的项目(ts)
  2. child-app2 使用cra创建的项目(ts),且引入MF
  3. child-app3 使用cra创建的项目(ts),且导出MF
    • 此项目与child-app2配合,尝试各种类型MF模块,具体见该目录下的README
  4. child-app4 使用cra创建的项目(js),且使用内部组件库
  5. module-dederation-demo mf相关项目
    1. app1 引入MF的项目
    2. app2 导出MF的项目
    3. app2 导出和引入MF的项目

项目介绍

相关库

  • 基座框架:react17
  • 路由:react-router-dom6
  • 组件库: antd 需要额外配置,如果重新做我会选择semi-ui这一类库做演示,因为不用配置比较方便(简单说一下,这两个现在都是使用babel-import-plugin实现的自动按需加载,这不是问题,主要在于antd使用了less会导致编译异常,需要额外下载less包以及配置vite.config.ts,比较麻烦)
  • 构建工具:webpack
    • 虽然这里配置了Vite,但是别用,因为Vite不兼容Webpack的MF特性,Vite有自己的MF插件系统
      • 如果你的前端微服务架构中不涉及MF,那么你用vite作为基座应用也是可以的
      • 你想用Vite的MF插件系统,完全抛弃webpack构建?那你会有很多坑需要克服:
        • 对于micro-app,如果父子应用都使用Vite会出错,解决起来很麻烦,还会失去很多重要特性--比如虚拟沙盒
        • 业务项目都是Webpack,改成Vite有额外的迁移成本,而且踩的坑对webpack项目基本没有参考价值

micro-app

构建思路

基座应用和子应用构建都使用webpack

理由之一是因为父子应用都使用vite会出现报错,虽然官方给出了解决方案,但是处理起来太麻烦,而且会丧失很多重要的特性,所以子应用使用webpack

另一个理由则是webpack5提供的Module Federation特性。

功能点

总览下需要的功能点,没想到的再补充:

  1. 可以在基座应用显示子应用
  2. 基座应用里切换url可以让子应用路由切换
  3. 数据通信
    1. 主应用 => 子应用
    2. 子应用 => 主应用
    3. 主应用 监听 子应用数据
    4. 子应用 监听 主应用数据
    5. 子应用 <=> 子应用:官方不推荐这种做法,但是可以通过全局数据实现
    6. 主应用 广播 子应用
  4. 子应用使用公共模块
    1. 运行Module Federation实例
    2. 将MF实例应用做为子应用引入基座
    3. 在子应用中引入远程模块
      1. webpack版本必须在5以上
      2. 需要修改webpack配置
      3. 动态引入

数据通信

不多做介绍,详见 官方文档 数据通信

Module Federation

功能点

  1. app1引用app2 单个组件
    1. 引用组件没有其他依赖
    2. 引用组件依赖app2其他组件
    3. 引用组件依赖其他app的组件
  2. app1引入多个app的多个组件
    1. 引入单个应用的多个组件
    2. 引入多个应用的单个组件
    3. 引入多个应用的多个组件
  3. 与远程组件交互(把远程组件当成普通的React组件使用就行)
    1. 传值给远端组件
    2. 接收远端组件的数据

项目启动及实践

目前此项目包含1个主项目+6个子项目,但是并不需要全部启动,这里先介绍下项目间的关系,请根据需要决定启动相应的项目。

项目关系

分为两部分,先介绍最重要的第一部分,请看:

其中Base就是micro-app-demo的主项目,也可以叫基座应用。

基座项目里使用了两个子项目child-app1child-app2

child-app1不依赖其他任何MF模块,启动后即可在基座应用查看效果。

child-app2依赖child-app3,其中child-app3抛出MFchild-app2引入MF使用。

一般来说会有这么几类需求:

  1. MF实践:项目了解remote项目是如何提供远程组件的,host项目是如何引用远程组件的,那么推荐这么启动:
    1. 启动child-app3
    2. 启动child-app2
  2. 微前端实践,了解子应用独立运行,以及在基座应用中的运行,推荐这么启动:
    1. 启动child-app1
    2. 启动基座项目
  3. micro-app + MF实践,子应用使用MF模块,基座应用中子应用运行,推荐这么启动:
    1. 启动child-app3
    2. 启动child-app2
    3. 启动基座项目
  4. 以上全部,启动整个架构,推荐这么启动
    1. 启动child-app1
    2. 启动child-app3
    3. 启动child-app2
    4. 启动基座项目

理论上在进行以上实践后对整个架构就基本了解了。

然后是第二部分,请见packages/module-federation-demo目录,这部分是纯MF的,是我从webpack5官方提供的Demo拿过来改了改,如果只是想实践MF,那么只用这部分可能会更简单、更纯粹一些,结构如下:

简单说明下:

  1. app1引用了app2app3抛出的MF
  2. app2只抛出MF
  3. app3引用了app2MF,并抛出自己的MF

如果要启动的话,推荐:

  1. 启动app2
  2. 启动app3
  3. 启动app1

这部分也可以整合到第一部分【其实本来也是这么做的,原本child-app2直接引用的这部分】,但是考虑到这会增加整个Demo项目结构的复杂度,所以最终创建了child-app3以提供MF,将第一部分和第二部分的分离。

启动项目

基座项目里提供了所有指令(micro-app-demo/package.json),如下:

{
   "scripts": {
      "start": "set PORT=3021 && react-app-rewired start",
      "start-vite": "vite --host",
      "start:child-app1": "cd packages/child-app1 && yarn start",
      "start:child-app2": "cd packages/child-app2 && yarn start",
      "start:child-app3": "cd packages/child-app3 && yarn start",
      "start:mf-app1": "cd packages/module-federation-demo && yarn start:app1",
      "start:mf-app2": "cd packages/module-federation-demo && yarn start:app2",
      "start:mf-app3": "cd packages/module-federation-demo && yarn start:app3",
      "install:main": "yarn",
      "install:child-app1": "cd packages/child-app1 && yarn",
      "install:child-app2": "cd packages/child-app2 && yarn",
      "install:child-app3": "cd packages/child-app3 && yarn",
      "install:mf-all": "cd packages/module-federation-demo && yarn install:all",
      "build": "react-app-rewired build",
      "test": "react-app-rewired test",
      "eject": "react-scripts eject"
   }
}

其实就两部分,一部分是安装依赖,一部分是启动项目。

安装依赖

  1. install:main 安装基座项目依赖
  2. install:child-app1 安装child-app1项目依赖
  3. install:child-app2 安装child-app2项目依赖
  4. install:child-app3 安装child-app3项目依赖
  5. install:mf-all 安装module-federation-demo全部子项目的依赖

启动项目

  1. start 启动基座项目--webpack
  2. start-vite 启动基座项目--vite
  3. start:child-app1 启动child-app1项目
  4. start:child-app2 启动child-app2项目
  5. start:child-app3 启动child-app3项目
  6. start:mf-app1 启动mf-app1项目
  7. start:mf-app2 启动mf-app2项目
  8. start:mf-app3 启动mf-app3项目