Skip to content

Commit

Permalink
fix(qiankun): add default classname and new laoding style (#758)
Browse files Browse the repository at this point in the history
* fix(qiankun): add min-height and default classname

* better code

* add max heigth
  • Loading branch information
chenshuai2144 authored Dec 7, 2021
1 parent 0a4954f commit 9a7f434
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 94 deletions.
28 changes: 1 addition & 27 deletions example/app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { InitialState, request as umiRequest, SelectLang } from 'umi';
import { InitialState, request as umiRequest } from 'umi';
import { MenuItem } from '@umijs/plugin-layout';

export function render(oldRender: Function) {
Expand All @@ -16,32 +16,6 @@ export const layout = {
logout: () => {
alert('退出登录成功');
},
// rightRender: (initialState: any, setInitialState: any) => {
// console.log('initialState', initialState);
// return (
// <>
// <SelectLang
// postLocalesData={locales => [
// ...locales,
// {
// lang: 'nl-NL', // 荷兰语的 key 与 antd 保持一致
// label: 'Nederlands', // 荷兰语的“荷兰语”
// icon: '🇳🇱', // 荷兰国旗
// title: 'Taal', // 荷兰语的“语言”
// },
// ]}
// onItemClick={({ key }) => alert(key)}
// />
// <button
// onClick={() => {
// setInitialState({ name: 'SS' });
// }}
// >
// {initialState.name}
// </button>
// </>
// );
// },
patchMenus: (menus: MenuItem[], initialInfo: InitialState) => {
if (initialInfo?.initialState?.name === 'test') {
return [
Expand Down
25 changes: 16 additions & 9 deletions packages/plugin-qiankun/src/master/AntdErrorBoundary.tsx.tpl
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
import React from 'react';
import { Button, Result } from 'antd';
import { getLocale } from 'umi';
import React from "react";
import { Button, Result } from "antd";
{{#enableLocale}}
import { getLocale } from "umi";
{{/enableLocale}}

const defaultLocale = 'en-US';
const defaultLocale = "en-US";

export const ErrorBoundary = ({ error }: { error: any }) => {
console.error(error);
let currentLocale = defaultLocale;
{{#enableLocale}}
currentLocale = getLocale ? getLocale() : defaultLocale;
{{/enableLocale}}

const currentLocale = getLocale ? getLocale() : defaultLocale;

return (
<Result
status="500"
title={
currentLocale === defaultLocale ? 'Whoops, something went wrong' : '出错了'
currentLocale === defaultLocale
? "Whoops, something went wrong"
: "出错了"
}
subTitle={
currentLocale === defaultLocale
? 'This page failed to load, please try again later'
: '页面加载失败,请稍后重试'
? "This page failed to load, please try again later"
: "页面加载失败,请稍后重试"
}
extra={
<Button type="primary" onClick={() => window.location.reload()}>
{currentLocale === defaultLocale ? 'Reload' : '再试一次'}
{currentLocale === defaultLocale ? "Reload" : "再试一次"}
</Button>
}
/>
Expand Down
29 changes: 18 additions & 11 deletions packages/plugin-qiankun/src/master/AntdLoader.tsx.tpl
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { Spin } from 'antd';
import React from 'react';
import { Spin } from "antd";
import React from "react";

export default function AntdLoader(props: {loading: boolean}) {
export default function AntdLoader(props: { loading: boolean }) {
const { loading } = props;
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
}

return <Spin spinning={loading} size="large" style={style}/>;
return (
<div
style={{
height: "100%",
width: "100%",
minHeight: 100,
display: "flex",
alignItems: "center",
justifyContent: "center",
maxHeight: "60vh",
}}
>
<Spin spinning={loading} size="large" />
</div>
);
}
2 changes: 1 addition & 1 deletion packages/plugin-qiankun/src/master/ErrorBoundary.tsx.tpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React from "react";

export const ErrorBoundary = ({ error }: { error: any }) => (
<div>{error?.message}</div>
Expand Down
102 changes: 65 additions & 37 deletions packages/plugin-qiankun/src/master/MicroApp.tsx.tpl
Original file line number Diff line number Diff line change
@@ -1,41 +1,57 @@
// @ts-ignore
// @ts-ignore
import { ErrorBoundary } from '@@/plugin-qiankun/ErrorBoundary';
import { getMasterOptions } from '@@/plugin-qiankun/masterOptions';
import { ErrorBoundary } from "@@/plugin-qiankun/ErrorBoundary";
import { getMasterOptions } from "@@/plugin-qiankun/masterOptions";
// @ts-ignore
import MicroAppLoader from '@@/plugin-qiankun/MicroAppLoader';
import { BrowserHistoryBuildOptions, HashHistoryBuildOptions, MemoryHistoryBuildOptions } from 'history-with-query';
import concat from 'lodash/concat';
import mergeWith from 'lodash/mergeWith';
import noop from 'lodash/noop';
import { FrameworkConfiguration, loadMicroApp, MicroApp as MicroAppType, prefetchApps } from 'qiankun';
import React, { forwardRef, Ref, useEffect, useImperativeHandle, useRef, useState } from 'react';
import MicroAppLoader from "@@/plugin-qiankun/MicroAppLoader";
import {
BrowserHistoryBuildOptions,
HashHistoryBuildOptions,
MemoryHistoryBuildOptions,
} from "history-with-query";
import concat from "lodash/concat";
import mergeWith from "lodash/mergeWith";
import noop from "lodash/noop";
import {
FrameworkConfiguration,
loadMicroApp,
MicroApp as MicroAppType,
prefetchApps,
} from "qiankun";
import React, {
forwardRef,
Ref,
useEffect,
useImperativeHandle,
useRef,
useState,
} from "react";
// @ts-ignore
import { History, useModel } from 'umi';
import { MasterOptions } from './types';
import { History, useModel } from "umi";
import { MasterOptions } from "./types";

const qiankunStateForSlaveModelNamespace = '@@qiankunStateForSlave';
const qiankunStateForSlaveModelNamespace = "@@qiankunStateForSlave";

type HashHistory = {
type?: 'hash';
type?: "hash";
} & HashHistoryBuildOptions;

type BrowserHistory = {
type?: 'browser';
type?: "browser";
} & BrowserHistoryBuildOptions;

type MemoryHistory = {
type?: 'memory';
type?: "memory";
} & MemoryHistoryBuildOptions;

export type Props = {
name: string;
settings?: FrameworkConfiguration;
base?: string;
history?:
| 'hash'
| 'browser'
| 'memory'
| "hash"
| "browser"
| "memory"
| HashHistory
| BrowserHistory
| MemoryHistory;
Expand Down Expand Up @@ -84,7 +100,9 @@ export const MicroApp = forwardRef(
// 未配置自定义 errorBoundary 且开启了 autoCaptureError 场景下,使用插件默认的 errorBoundary,否则使用自定义 errorBoundary
const microAppErrorBoundary =
errorBoundary ||
(propsFromParams.autoCaptureError ? (e) => <ErrorBoundary error={e} /> : null);
(propsFromParams.autoCaptureError
? (e) => <ErrorBoundary error={e} />
: null);

// 配置了 errorBoundary 才改 error 状态,否则直接往上抛异常
const setComponentError = (error: any) => {
Expand All @@ -111,16 +129,16 @@ export const MicroApp = forwardRef(
if (!appConfig) {
setComponentError(
new Error(
`[@umijs/plugin-qiankun]: Can not find the configuration of ${name} app!`,
),
`[@umijs/plugin-qiankun]: Can not find the configuration of ${name} app!`
)
);
}
return noop;
}, []);

// 约定使用 src/app.ts/useQiankunStateForSlave 中的数据作为主应用透传给微应用的 props,优先级高于 propsFromConfig
const stateForSlave = (useModel || noop)(
qiankunStateForSlaveModelNamespace,
qiankunStateForSlaveModelNamespace
);
const { entry, props: propsFromConfig = {} } = appConfig || {};

Expand All @@ -146,36 +164,38 @@ export const MicroApp = forwardRef(
},
configuration,
mergeWith({}, globalLifeCycles, lifeCycles, (v1, v2) =>
concat(v1 ?? [], v2 ?? []),
),
concat(v1 ?? [], v2 ?? [])
)
);

// 当配置了 prefetch true 时,在第一个应用 mount 完成之后,再去预加载其他应用
if (prefetch && prefetch !== 'all' && noneMounted) {
if (prefetch && prefetch !== "all" && noneMounted) {
microAppRef.current?.mountPromise.then(() => {
if (noneMounted) {
if (Array.isArray(prefetch)) {
const specialPrefetchApps = apps.filter(
(app) => app.name !== name && prefetch.indexOf(app.name) !== -1,
(app) => app.name !== name && prefetch.indexOf(app.name) !== -1
);
prefetchApps(specialPrefetchApps, configuration);
} else {
const otherNotMountedApps = apps.filter((app) => app.name !== name);
const otherNotMountedApps = apps.filter(
(app) => app.name !== name
);
prefetchApps(otherNotMountedApps, configuration);
}
noneMounted = false;
}
});
}

(['loadPromise', 'bootstrapPromise', 'mountPromise'] as const).forEach(
(["loadPromise", "bootstrapPromise", "mountPromise"] as const).forEach(
(key) => {
const promise = microAppRef.current?.[key];
promise.catch((e) => {
setComponentError(e);
setLoading(false);
});
},
}
);

return () => unmountMicroApp(microAppRef.current);
Expand All @@ -191,7 +211,7 @@ export const MicroApp = forwardRef(
// 确保 microApp.update 调用是跟组件状态变更顺序一致的,且后一个微应用更新必须等待前一个更新完成
updatingPromise.current = updatingPromise.current.then(() => {
const canUpdate = (microApp?: MicroAppType) =>
microApp?.update && microApp.getStatus() === 'MOUNTED';
microApp?.update && microApp.getStatus() === "MOUNTED";
if (canUpdate(microApp)) {
const props = {
...propsFromConfig,
Expand All @@ -200,16 +220,16 @@ export const MicroApp = forwardRef(
setLoading,
};

if (process.env.NODE_ENV === 'development') {
if (process.env.NODE_ENV === "development") {
if (Date.now() - updatingTimestamp.current < 200) {
console.warn(
`[@umijs/plugin-qiankun] It seems like microApp ${name} is updating too many times in a short time(200ms), you may need to do some optimization to avoid the unnecessary re-rendering.`,
`[@umijs/plugin-qiankun] It seems like microApp ${name} is updating too many times in a short time(200ms), you may need to do some optimization to avoid the unnecessary re-rendering.`
);
}

console.info(
`[@umijs/plugin-qiankun] MicroApp ${name} is updating with props: `,
props,
props
);
updatingTimestamp.current = Date.now();
}
Expand All @@ -235,13 +255,21 @@ export const MicroApp = forwardRef(
: null);

return Boolean(microAppLoader) || Boolean(microAppErrorBoundary) ? (
<div style={{ position: 'relative' }} className={wrapperClassName}>
<div
style={{ position: "relative" }}
className={`${wrapperClassName} qiankun-micro-app`}
>
{Boolean(microAppLoader) && microAppLoader(loading)}
{Boolean(microAppErrorBoundary) && Boolean(error) && microAppErrorBoundary(error)}
<div ref={containerRef} className={className} />
{Boolean(microAppErrorBoundary) &&
Boolean(error) &&
microAppErrorBoundary(error)}
<div
ref={containerRef}
className={`${className} qiankun-micro-app-container`}
/>
</div>
) : (
<div ref={containerRef} className={className} />
);
},
}
);
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import React, { useRef, useEffect, useCallback } from 'react';
import { MicroApp, Props as MicroAppProps } from './MicroApp';
import React, { useRef, useEffect, useCallback } from "react";
import { MicroApp, Props as MicroAppProps } from "./MicroApp";

export interface Props extends MicroAppProps {
history?: never
history?: never;
}

export function MicroAppWithMemoHistory(componentProps: Props) {
const { url, ...rest } = componentProps;
const history = useRef();
// url 的变更不会透传给下游,组件内自己会处理掉,所以这里直接用 ref 来存
const historyOpts = useRef({
type: 'memory',
type: "memory",
initialEntries: [url],
initialIndex: 1,
});
const historyInitHandler = useCallback(h => history.current = h, []);
const historyInitHandler = useCallback((h) => (history.current = h), []);

useEffect(() => {
// push history for slave app when url property changed
Expand All @@ -36,5 +36,5 @@ export function MicroAppWithMemoHistory(componentProps: Props) {
history={historyOpts.current}
onHistoryInit={historyInitHandler}
/>
)
);
}
11 changes: 8 additions & 3 deletions packages/plugin-qiankun/src/master/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,14 @@ export default function (api: IApi) {
api.writeTmpFile({
path: 'plugin-qiankun/ErrorBoundary.tsx',
// 开启了 antd 插件的时候,使用 antd 的 ErrorBoundary,否则提示用户必须设置一个自定义的 ErrorBoundary 组件
content: api.hasPlugins(['@umijs/plugin-antd'])
? readFileSync(join(__dirname, 'AntdErrorBoundary.tsx.tpl'), 'utf-8')
: readFileSync(join(__dirname, 'ErrorBoundary.tsx.tpl'), 'utf-8'),
content: utils.Mustache.render(
api.hasPlugins(['@umijs/plugin-antd'])
? readFileSync(join(__dirname, 'AntdErrorBoundary.tsx.tpl'), 'utf-8')
: readFileSync(join(__dirname, 'ErrorBoundary.tsx.tpl'), 'utf-8'),
{
enableLocale: api.hasPlugins(['@umijs/plugin-locale']),
},
),
});

api.writeTmpFile({
Expand Down

0 comments on commit 9a7f434

Please sign in to comment.