Skip to content

微前端

概念

微前端借鉴了微服务的概念,将一个庞大的应用拆分成多个灵活的小应用,每个应用都可以独立开发,独立运行,独立部署,还可以随意组合,这样减低了耦合度,从而更加灵活

特性

可以多团队,不限技术栈,相互之间互不依赖

  • 技术栈无关

    主框架不限制接入的技术栈,子应用可自主选择技术栈(vue、react)

  • 独立开发/部署

    各个团队之间仓库独立,单独部署,互不依赖

  • 增量升级:

    具备渐进式升级的特性(简称需要啥装啥)

  • 独立运行时

    微应用之间运行时互不依赖,有独立的状态管理

微前端方案

iframe 方案

特点

  • 接入比较简单
  • 隔离非常稳

不足

  • dom 割裂感严重,弹窗只能在 iframe,而且有滚动条
  • 通信麻烦
  • 前进后退按钮无效

qiankun 方案

qiankun 方案是基于 single-spa 的微前端方案。

micro-app 方案

micro-app 是基于 webcomponent + qiankun sandbox 的微前端方案。

EMP 方案

EMP 方案是基于 webpack 5 module federation 的微前端方案。

无界微前端 方案

特点

  • 接入简单,代码量少
  • 不需要针对 vite 额外处理
  • 预加载
  • 应用保活机制

不足

  • 隔离 js 使用一个空的 iframe 进行隔离
  • 子应用 axios 需要自行适配
  • iframe 沙箱的 src 设置了主应用的 host,初始化 iframe 的时候需要等待 iframe 的 location.orign 从'about:blank'初始化为主应用的 host,这个采用的计时器去等待的不是很优雅。

参考网址

无界:https://wujie-micro.github.io/doc/

微前端:https://juejin.cn/post/7212603829572911159?searchId=20240311102708740158C08B84D2A1BC4C#heading-10

创建主应用

sh
npm init vue

image-20240311101242533

创建子应用

sh
npm init vite

image-20240311101616599

初始化项目

sh
pnpm init

生成 package.json

monorepo 架构

采用的是微前端一个主应用,和多个子应用,我们采用 monorepo 架构 一次 install 即可安装完成。

不用一个一个去 install 安装依赖

第一步 安装 pnpm

全局安装 pnpm

sh
npm i pnpm -g

第二步 配置 Monorepo

在根目录新建一个 pnpm-workspace.yaml 配置依赖项

yaml
packages:
  # all packages in direct subdirs of packages/
  - 'main'
  # all packages in subdirs of components/
  - 'web/**'

配置完成后 install 一次就行

他会把所有的公共依赖项抽到外层,而里层的依赖项都是一些最核心的


安装依赖

sh
pnpm i

最外部的公共依赖包含所有

里层只会放进去项目对应的相关的依赖

很厉害

image-20240311104406163

创建公共文件

创建了一个 utils

名字需要是 index

image-20240311113500486

初始化

sh
pnpm init

配置 Monorepo

yaml
packages:
  # all packages in direct subdirs of packages/
  - 'main'
  # all packages in subdirs of components/
  - 'web/**'
  # 新增 公共文件 -  utils
  - 'utils'

创建 request

用来封装 axios

安装 axios

sh
pnpm i axios

建立链接 main--utils

sh
# main 建立连接
pnpm -F main add utils

# main 建立连接
pnpm -F react add utils

# main 建立连接
pnpm -F vue add utils

image-20240311110605798

引用公共文件

在 main.js 文件中可以引用

子应用相同

image-20240311111448212

无界-微前端

安装依赖

在主应用中安装 无界的包

sh
pnpm i wujie

默认库为 pnpm i wujie

无界文档有常用框架封装好的 不需要手动封装, pnpm 安装 下面的就好

sh
# vue2 框架
pnpm i wujie-vue2 -S
# vue3 框架
pnpm i wujie-vue3 -S
# react 框架
pnpm i wujie-react -S

在主应用中引入 什么框架安装什么就好

image-20240311112828617

引入依赖

第一步 引入 引入对应的框架(这里是 vue3)

第二步 挂载

image-20240311113029694

启动应用

启动主应用与子应用

sh
pnpm run dev

image-20240311113842290

效果

image-20240311120029848

无界-传参(项目之间的通信)

三种传参方式

通过 window 进行通讯

通过 window.parent.name 接收参数

js
// 主应用定义变量
window.name = ref('明楼');

// 子应用 vue3
const name = ref(window.parent.name); // 明楼

// 子应用 react
const [name] = useState(window.parent.name); // 明楼

通过 Props 给子应用注入参数

通过在 Wujie 组件上 通过 props 进行传参

html
<WujieVue
  :props="{name:'明楼',age:26}"
  url="http://127.0.0.1:5174/"
  name="vue3" />

接收通过 window.$wujie.props 获取

js
// vue3
let obj = ref(window.$wujie.props);

// react

错误处理 TS 文件中 $wujie 会报错

js
// 报错$wujie 可以添加声明文件  在minjs中

declare global {
    interface Window {
        $wujie:{
            props:Record<string,any>
        }
    }
}

event Bus

创建 事件总线 event bus

jsx
// 主应用 接收数据
bus.$on('vue', (data: any) => {
  console.log(data);
});

bus.$on('React', (data: any) => {
  console.log(data);
});

// 子应用 发送数据
// vue3
let data = ref('我是Vue3的数据');
const send = () => {
  window.$wujie.bus.$emit('vue', data.value);
};

// react
<button
  onClick={() => {
    window.$wujie.bus.$emit('React', '我是React');
  }}>
  我是React的按钮
</button>;