微前端

886 阅读3分钟

一、微前端

1、微前端是什么

微前端的核心在于将一个庞大的前端应用拆分成多个独立灵活的小型应用,每个应用都可以独立开发、独立运行、独立部署,再将这些小型应用融合为一个完整的应用,或者将原本运行已久、没有关联的几个应用融合为一个应用。

2、微前端的优势

  • 不限制技术栈

  主框架不限制接入应用的技术栈,主应用是React,子应用可以是React,也可以是Vue。

  • 增量升级

  在对大型的项目进行升级和重构的时候,微前端是一种非常方便快捷的手段。

  • 独立开发和部署

  子应用的代码仓库独立,修改之后可以独立部署。

  • 可以独立运行

  每个子应用之间状态隔离。

二、主流的微前端框架

1、乾坤

官网地址:qiankun.umijs.org/zh/guide

2、micro-app

官网地址:jd-opensource.github.io/micro-app/d…

使用例子:

  1. 主应用引入micro-app。
npm i @micro-zoe/micro-app --save

2. 在入口函数进行配置。

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

microApp.start();

3. 加载子应用。

import React from 'react';

export default function Index() {
  return <div>
     <micro-app
      name='vue-app' //子应用名称必传
      url='http://localhost:3001/' //子应用地址必传
      router-mode='native' //路由模式默认是search模式
      disable-scopecss //关闭样式隔离
      iframe //沙箱模式默认是with模式
      ></micro-app>
  </div>;
}

micro-app有两种沙箱模式,with沙箱和iframe沙箱,默认是with沙箱。如果使用的是Vite的话需要使用iframe沙箱。

在TypeScript中使用的时候,micro-app是自定义元素,需要声明。

declare namespace JSX {
  interface IntrinsicElements {
    'micro-app': {
      name: string;
      url: string;
      [key: string]: any; // 允许其他自定义属性
    };
  }
}

4. 子应用

子应用如果是webpack,需要设置跨域,Vite默认开启跨域,无需设置。

module.exports = {
    devServer: {
        headers: {
        'Access-Control-Allow-Origin': '*',
        }
     }
}

子应用注册卸载函数。

// main.jsconst app = createApp(App)
app.mount('#app')// 卸载应用

window.unmount = () => {
  app.unmount()
}

如果在TypeScript中使用,unmount也需要进行声明。

declare global {
  interface Window {
    unmount?: () => void;
  }
}

export {};

3、无界

官网地址:wujie-micro.github.io/doc/guide/

使用例子:

  1. 主应用引入无界。
npm i wujie-react --save

2. 在入口函数进行配置。

const { setupApp, preloadApp } = WujieReact;
const degrade = window.localStorage.getItem('degrade') === 'true' || !window.Proxy || !window.CustomElementRegistry;

setupApp({
  name: 'vue3', //唯一用户;必传。
  url: 'http://localhost:3001', //需要渲染的子应用的url;必传。
  exec: true, //预执行;非必传。
  alive: true, //子应用保活,state不会丢失;非必传。
  plugins: [
    {
      patchElementHook(element: any, iframeWindow) {
        if (element.nodeName === 'STYLE') {
          element.insertAdjacentElement = function (_position, ele) {
            iframeWindow.document.head.appendChild(ele);
          };
        }
      },
    }, // vite4 子应用样式切换丢失修改
  ], // 子应用插件。
  degrade, // 浏览器不支持时,子应用采用降级iframe方案;非必传。
});

// 预加载子应用,预加载能力可以极大的提升子应用打开的首屏时间
preloadApp({
  name: 'vue3',
  url: 'http://localhost:3001',
});

3. 在页面中引入。

import React from 'react';
import WujieReact from 'wujie-react';
import { useNavigate, useLocation } from 'react-router-dom';

const { bus } = WujieReact;

export default function Vue3() {
  const location = useLocation();
  const navigation = useNavigate();
  const path = location.pathname.replace('/vue3-sub', '').replace('/vue3', '');

  // 告诉子应用要跳转哪个路由
  path && WujieReact.bus. $emit('vue3-router-change', path);
  const props = {
    jump: (name) => {
      navigation(`/${name}`);
    },
  };

  bus. $on("WDP-Vue", (name, path) => {
    console.log('----', name, path);
  });

  return (
    <WujieReact
      width='100%'
      height='100%'
      name='vue3'
      url={'http://localhost:3001'}
      sync={!path}
      props={props}
    ></WujieReact>
  );
}

4. 结果

主应用成功展示子应用界面。

子应用可以单独运行。