ant Design Pro + umi3 + umi-qiankun 配置微前端服务平台

3,437 阅读3分钟

需求: 平台化产品例如:A, B项目两个项目在平台里面可以实现访问A B两个项目的路由和页面,同时AB项目彼此独立。摒弃ifrname实现效果。

1、找到啦umi-qiankun这个插件可以实现: 前提技术栈:umi构建,如Ant Design Pro; 我用的是Ant Design Pro; 所以接下来就准备构建Ant Design Pro 项目;备注(因为umi3发布,Ant Design Pro 项目没有js, ts的选择,不管选啥都是ts.umi3改动比较大,所以配置也跟以前不同。网上案例不多,自己总结下。)。

2、准备好两个项目(一个项目作为载体【项目命名为aircraftCarrier】,另外一个项目作为子项目可以寄生在载体上【项目命名为parasite1】。同时 子项目可以独立运行); 安装umi-qiankun;

npm i @umijs/plugin-qiankun -S  
or
yarn add @umijs/plugin-qiankun

在载体aircraftCarrier/config/新建apps.js(名字自定义);

export default [
  {
    name: 'parasite1', // 儿子的名字(不重复就行)
    entry: '//localhost:8001', // 子项目服务
    base: '/parasite1', // 子项目在父级项目的路由
    mountElementId: 'root-slave',  // 载体ID
  },
];

请你跟我这样做: 找到config/config.ts目录:将apps.js导入。

import apps from './apps';  
// 将qiankun插件导入,umi3怎么导入插件的自己查文档。qiankun放在defineConfig对象里面
qiankun: {
    master: {
      defer: true, // 为true时才能手动启动
      jsSandbox: true,
      prefetch: true
    }
  },

还在当前文件修改routes:

{
	path: '/',
	component: '../layouts/BlankLayout', // 选一个布局(最好空白布局)
	routes: [
        {
          path: '/', 
          component: './Welcome'  // 这里可以注册载体项目的路由。
        }, 
        { 
          path: '/parasite1' // 子项目与apps.js base设置相同
        }, 
        { 
        .....任意多个项目
    }]
},

接下来我们来设置:document.ejs,因为react跟目录都是root为啦避免冲突将root改啦:

<div id="root">
改为
<div id="<%= context.config.mountElementId %>">

接下来我们来设置layouts/BlankLayout.tsx

// 设置各个子项目tab切换页,根据config.js的路由进行配置。
<div className={className}>
      <Link style={{color: '#fff',fontWeight: 'bold'}} to="/">
        <div className={styles.tabStyle}>
          载体平台 
        </div>
      </Link>
      <Link style={{color: '#fff', fontWeight: 'bold'}} to="/parasite1">
        <div className={styles.tabStyle}>
        子项目
        </div>
      </Link>
    </div>

大概就是这个样子,自行配置自己的。 这个页面会有个坑。 我需要自行启动也就是上面说的当 defer: true, // 为true时才能手动启动; 所以记得设置;接下来再设置 layouts/BlankLayout.tsx;也就是当前这个页面。 怎么手动启动呢:

import { qiankunStart } from 'umi';

useEffect(() => {
    setTimeout(qiankunStart, 100); // 这样就手动启动啦
  }, [])

如果你不手动启动就会遇见在这个bug

设置完啦就没事啦

不要着急;不是说root名字改啦吗,那引入的子项目也直接放在载体跟元素里面吗? 子项目需要设置自己的根元素

// 在布局页面加上这个。
<div id="root-slave"></div>

我在开发的时候自己遇见一个错。

<>
    <div className={styles.header_aircraftCarrier}>
      <RightContent />
    </div>
    <div id="root-slave">{children}</div>
    </>

我把{children}放进啦放子项目的跟元素里面,当切换tab的时候就发现来回切换就会报 如下错误

<>
    <div className={styles.header_aircraftCarrier}>
      <RightContent />
    </div>
    {children}
    <div id="root-slave"></div>
    </>

放在外面就不报错啦。

接下来 就需要配置子项目啦:

我的子项目名字叫做parasite1 先安装umi-qiankun;

npm i @umijs/plugin-qiankun -S  
or
yarn add @umijs/plugin-qiankun

这个时候就该配置config.tsx啦;

// qiankun放在defineConfig对象里面
qiankun: {
    slave: {
    }
  },

没错umi3就这么配置; 如果不配置就会报如下错误

接下来配置子项目跟元素

// mountElementId放在defineConfig对象里面
mountElementId: "parasite1-root",

接下来配置子项目下的 document.ejs,

<div id="<%= context.config.mountElementId %>">

这个时候应该本地启动(注意子项目端口应该和载体项目apps.js里面注册的端口一致); 还有一点需要注意子项目注册的路由和载体apps.js里面注册的仔细看看,有可能遇见意想不到的问题。 github.com/17698753015… dev分支是最新版的