Skip to content

Commit

Permalink
feat: refactor-microapp (#2853)
Browse files Browse the repository at this point in the history
  • Loading branch information
bravepg authored Dec 25, 2023
1 parent a826cf5 commit 9ec1595
Show file tree
Hide file tree
Showing 12 changed files with 10,710 additions and 12,839 deletions.
7 changes: 7 additions & 0 deletions .changeset/forty-teachers-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@qiankunjs/ui-shared': patch
'@qiankunjs/react': patch
'@qiankunjs/vue': patch
---

feat: refactor the code of microapp
10 changes: 6 additions & 4 deletions examples/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
"main": "index.js",
"scripts": {
"start": "webpack-dev-server",
"start:react": "cross-env MODE=react webpack-dev-server",
"start:vue": "cross-env MODE=vue webpack-dev-server",
"start:vue3": "cross-env MODE=vue3 webpack-dev-server",
"start:multiple": "cross-env MODE=multiple webpack-dev-server",
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\""
},
"author": "",
"devDependencies": {
Expand All @@ -26,9 +27,10 @@
"webpack-dev-server": "^3.9.0"
},
"dependencies": {
"qiankun": "^2.10.10",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"@qiankunjs/react": "^0.0.1-rc.12",
"qiankun": "^3.0.0-rc.15",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"vue": "^3.3.9",
"zone.js": "^0.10.2",
"@vue/composition-api": "1.7.2"
Expand Down
66 changes: 48 additions & 18 deletions examples/main/render/ReactRender.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
import React from 'react';
import ReactDOM from 'react-dom';

/**
* 渲染子应用
*/
function Render(props) {
const { loading } = props;

return (
<>
{loading && <h4 className="subapp-loading">Loading...</h4>}
<div id="subapp-viewport" />
</>
);
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom/client';
import { MicroApp } from '@qiankunjs/react';
// 调试使用,注意 React 多实例问题
// import { MicroApp } from '../../../packages/ui-bindings/react/dist/esm/';
import '../index.less';

const root = ReactDOM.createRoot(
document.getElementById('subapp-container'),
);
const sidemenu = document.querySelector('.mainapp-sidemenu');

const microApps = [
{ name: 'react15', entry: '//localhost:7102' },
{ name: 'react16', entry: '//localhost:7100' },
];

function App() {
const [appName, setAppName] = useState('');

const handleMenuClick = (e) => {
const app = microApps.find((app) => app.name === e.target.dataset.value);
if (app && app.name !== appName) {
setAppName(app.name);
} else {
console.log('not found any app');
}
}

useEffect(() => {
sidemenu.addEventListener('click', handleMenuClick);

return () => {
sidemenu.removeEventListener('click', handleMenuClick);
}
}, []);

if (appName) {
const appEntry = microApps.find((app) => app.name === appName)?.entry;
return <MicroApp name={appName} entry={appEntry} autoCaptureError />;
}

return null;
}

export default function render({ loading }) {
const container = document.getElementById('subapp-container');
ReactDOM.render(<Render loading={loading} />, container);
function reactRender() {
// 将组件挂载到指定的节点上
root.render(<App />);
}

reactRender();
2 changes: 2 additions & 0 deletions examples/main/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ const path = require('path');

const modeEntryMap = {
multiple: './multiple.js',
react: './render/ReactRender.jsx',
vue: './render/VueRender.js',
vue3: './render/Vue3Render.js',
undefined: './render/VanillaRender.js',
}

const modeHTMLMap = {
multiple: './multiple.html',
react: './index.html',
vue: './index.html',
vue3: './index.html',
undefined: './index.html',
Expand Down
5 changes: 3 additions & 2 deletions examples/react15/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
},
"browserslist": [
"last 2 Chrome versions"
]
}
],
"repository": "[email protected]:umijs/qiankun.git"
}
2 changes: 1 addition & 1 deletion examples/react16/.rescriptsrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const QiankunPlugin = require('../../packages/webpack-plugin/dist/cjs');
const { QiankunPlugin } = require('../../packages/webpack-plugin/dist/cjs');


module.exports = {
Expand Down
10 changes: 4 additions & 6 deletions packages/ui-bindings/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,16 @@
"author": "Bravepg",
"license": "MIT",
"dependencies": {
"lodash": "^4.17.11",
"@qiankunjs/ui-shared": "workspace:^"
"@qiankunjs/ui-shared": "workspace:^",
"lodash": "^4.17.11"
},
"devDependencies": {
"@types/react": "^18.0.0",
"eslint-plugin-react": "^7.33.2",
"qiankun": "workspace:^",
"react": "^18.2.0"
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"peerDependencies": {
"qiankun": "3.0.0-rc.15",
"@qiankunjs/ui-shared": "0.0.0",
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
},
Expand Down
53 changes: 25 additions & 28 deletions packages/ui-bindings/react/src/MicroApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@ function useDeepCompare<T>(value: T): T {
}

export const MicroApp = forwardRef((componentProps: Props, componentRef: Ref<MicroAppType | undefined>) => {
const { name, loader, errorBoundary, wrapperClassName, className, ...restProps } = componentProps;

const propsFromParams = omitSharedProps(restProps);
const { name, autoSetLoading, autoCaptureError, wrapperClassName, className, loader, errorBoundary } = componentProps;

const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error>();
const containerRef = useRef<HTMLDivElement>(null);
const microAppRef = useRef<MicroAppType>();

// 未配置自定义 errorBoundary 且开启了 autoCaptureError 场景下,使用插件默认的 errorBoundary,否则使用自定义 errorBoundary
const microAppErrorBoundary =
errorBoundary || (propsFromParams.autoCaptureError ? (e) => <ErrorBoundary error={e} /> : null);
const microAppErrorBoundary = errorBoundary || (autoCaptureError ? (e) => <ErrorBoundary error={e} /> : null);

// 配置了 errorBoundary 才改 error 状态,否则直接往上抛异常
const setComponentError = (e: Error | undefined) => {
Expand All @@ -48,32 +47,35 @@ export const MicroApp = forwardRef((componentProps: Props, componentRef: Ref<Mic
}
};

const containerRef = useRef<HTMLDivElement>(null);
const microAppRef = useRef<MicroAppType>();
const onError = (e: Error) => {
setComponentError(e);
setLoading(false);
};

useImperativeHandle(componentRef, () => microAppRef.current);

useEffect(() => {
mountMicroApp({
props: componentProps,
prevMicroApp: microAppRef.current,
container: containerRef.current!,
setMicroApp(app) {
microAppRef.current = app;
},
setLoading: (l) => {
setLoading(l);
},
componentProps,
setLoading,
setError: setComponentError,
});
})
.then((app) => {
microAppRef.current = app;
})
.catch((e: Error) => {
onError(e);
});

return () => {
const microApp = microAppRef.current;
if (microApp) {
if (microApp && microApp.getStatus() === 'MOUNTED') {
// 微应用 unmount 是异步的,中间的流转状态不能确定,所有需要一个标志位来确保 unmount 开始之后不会再触发 update
microApp._unmounting = true;
unmountMicroApp(microApp).catch((e: Error) => {
setComponentError(e);
setLoading(false);
onError(e);
});
}
};
Expand All @@ -82,22 +84,17 @@ export const MicroApp = forwardRef((componentProps: Props, componentRef: Ref<Mic
useEffect(() => {
updateMicroApp({
name,
propsFromParams,
getMicroApp() {
return microAppRef.current;
},
setLoading: (l) => {
setLoading(l);
},
key: 'react',
microApp: microAppRef.current,
microAppProps: omitSharedProps(componentProps),
setLoading,
});

return noop;
}, [useDeepCompare(propsFromParams)]);
}, [useDeepCompare(omitSharedProps(componentProps))]);

// 未配置自定义 loader 且开启了 autoSetLoading 场景下,使用插件默认的 loader,否则使用自定义 loader
const microAppLoader =
loader || (propsFromParams.autoSetLoading ? (loadingStatus) => <MicroAppLoader loading={loadingStatus} /> : null);
loader || (autoSetLoading ? (loadingStatus) => <MicroAppLoader loading={loadingStatus} /> : null);

const microAppWrapperClassName = wrapperClassName
? `${wrapperClassName} qiankun-micro-app-wrapper`
Expand Down
Loading

0 comments on commit 9ec1595

Please sign in to comment.