四月份啟動了一個(gè)ERP項(xiàng)目,基礎(chǔ)架構(gòu)設(shè)計(jì)采用了微前端(qiankun)+ ant-design-pro,開始一時(shí)爽,后面火葬場,這里記錄一下這次實(shí)踐的過程。直接看DEMO點(diǎn)這里
1. 創(chuàng)建主應(yīng)用
1.1 通過umi 初始化 ant-design-pro
// 通過umi初始化項(xiàng)目
npm create umi
...
1.2 安裝qiankun
npm i --save qiankun
1.3 添加初始化的項(xiàng)目中的src目錄下添加app.js用來注冊子應(yīng)用
import { registerMicroApps } from 'qiankun';
registerMicroApps(
[
{
name: 'microSubA',
entry: '//localhost:8002',
container: '#microSubApp',
activeRule: '/microSubA',
props: {
parentHistory: history
}
},
{
name: 'microSubB',
entry: '//localhost:8001',
container: '#microSubApp',
activeRule: '/microSubB',
props: {
parentHistory: history
}
}
],
)
1.4 在Layout中添加子應(yīng)用掛載點(diǎn),這里選擇了Layout中BasicLayout.jsx中添id為microSubAppdd的DOM掛載點(diǎn),大致代碼如下:
....
return (
<ProLayout
navTheme="light"
menuHeaderRender={false}
menuDataRender={menuDataRender}
onCollapse={handleMenuCollapse}
{...props}
{...settings}
breadcrumbRender={(routers = []) => [
{
path: '/',
breadcrumbName: formatMessage({
id: 'menu.home',
}),
},
...routers,
]}
itemRender={(route, params, routes, paths) => {
const first = routes.indexOf(route) === 0;
return first ? (
<Link to={paths.join('/')}>{route.breadcrumbName}</Link>
) : (
<span>{route.breadcrumbName}</span>
);
}}
rightContentRender={() => (
<DateTip />
)}
menuItemRender={(menuItemProps, defaultDom) => {
if (menuItemProps.isUrl || menuItemProps.children || !menuItemProps.path) {
return defaultDom;
}
return <Link to={menuItemProps.path}>{defaultDom}</Link>;
}}
>
<Authorized authority={authorized.authority} noMatch={noMatch}>
{children}
</Authorized>
<div id="microSubApp" />
</ProLayout>
);
....
1.5 等Layout渲染完成,調(diào)用qiankun的start()啟動qiankun, 在BasicLayout.jsx中添加start啟動
useEffect(() => {
if (dispatch) {
start({
sandbox: false,
});
}
}, []);
到這里完成了主應(yīng)用的添加,下面開始添加子應(yīng)用
2. 子應(yīng)用添加
2.1 初始化一個(gè)ant-design-pro項(xiàng)目
2.2 子應(yīng)用不需要使用qiankun,只需在app.js中導(dǎo)出qiankun需要的生命周期就可以了。因?yàn)槲覀兪褂玫膗mi相關(guān),這里需要使用umi-plugin-qiankun插件,這個(gè)需要注意自己umi的版本,我這邊子應(yīng)用是umi2.x版本,所以安裝的插件是"@umijs/plugin-qiankun": "^1.3.2"
2.3 修改子應(yīng)用的config.js相關(guān)的配置信息
// 在plugins中添加插件的使用 umi2.x才需要手動載入
const plugins = [
['@umijs/plugin-qiankun'],
....
]
// 添加如下配置
export defualt {
// 這里microSubA就是子應(yīng)用的名稱
...
publicPath: '/microSubA/',
base: '/microSubA',
mountElementId: 'root-slave', // 子應(yīng)用自己渲染的DOM節(jié)點(diǎn)
}
2.4 修改src/pags/document.ejs把子應(yīng)用的掛載點(diǎn)修改為config中配置的mountElementId避免
// 默認(rèn)<div id="root">修改為
<div id="<%= context.config.mountElementId %>">
2.5 修改該package.json中name為子應(yīng)用的名稱
到這里我們已經(jīng)用qiankun和ant-design-pro實(shí)現(xiàn)了微前端架構(gòu),下面列舉一些常見的問題。
常見問題
一定要仔細(xì)看官網(wǎng)的常見問題,大部分遇到的問題都可以解決,https://qiankun.umijs.org/zh/faq/#application-died-in-status-loading-source-code-you-need-to-export-the-functional-lifecycles-in-xxx-entry
1. "Application died in status LOADING_SOURCE_CODE: You need to export the functional lifecycles in xxx entry"
這個(gè)是一個(gè)最最最常見的問題,可能每個(gè)人遇到它的方式都不同,我是加載第一個(gè)子應(yīng)用正常,加載第二個(gè)子應(yīng)用報(bào)這個(gè)錯(cuò)誤,最后發(fā)現(xiàn)是子應(yīng)用的package.json中的name一樣了
2. 第二次訪問同一個(gè)子應(yīng)用總是被重定向到離開之前的子應(yīng)用頁面
這個(gè)應(yīng)該是qiankun1.x會有的問題,使用qiankun2.0
3. 子應(yīng)用啟動報(bào):AssertionError [ERR_ASSERTION]: Document src/pages/document.ejs must contain <div id="root-slave">
確實(shí)一下上面的2.4步驟是否設(shè)置了
4. 啟動相關(guān)沒有報(bào)錯(cuò),但就是沒有加載出子應(yīng)用
檢測一下start調(diào)用了沒有,子應(yīng)用掛載的DOM是否在start調(diào)用的時(shí)候已經(jīng)渲染好了