Merge branch 'qiankun' into vue3

This commit is contained in:
harrywan 2021-04-19 20:05:27 +08:00
commit daeb5aab04
10 changed files with 156 additions and 14 deletions

View File

@ -2,6 +2,7 @@
<div>
main
</div>
<MicroAppWithMemoHistory name="app1" :url="url" />
</template>
<config>
{
@ -9,3 +10,22 @@
"title": "首页"
}
</config>
<script>
import { ref, onMounted } from 'vue';
import { MicroAppWithMemoHistory } from '@fesjs/fes';
export default {
components: { MicroAppWithMemoHistory },
setup() {
const url = ref('/app1/test');
onMounted(() => {
setTimeout(() => {
url.value = '/app1';
}, 3000);
});
return {
url
};
}
};
</script>

View File

@ -33,6 +33,7 @@ export default function (api) {
modifyRoutes({ api, namespace });
const absMicroAppPath = join(namespace, 'MicroApp.js');
const absMicroAppWithMemoHistoryPath = join(namespace, 'MicroAppWithMemoHistory.js');
const absRuntimePath = join(namespace, 'runtime.js');
const absMasterOptionsPath = join(namespace, 'masterOptions.js');
const absGetMicroAppRouteCompPath = join(
@ -62,6 +63,15 @@ export default function (api) {
)
});
api.writeTmpFile({
path: absMicroAppWithMemoHistoryPath,
content: Mustache.render(
readFileSync(join(__dirname, 'runtime/MicroAppWithMemoHistory.tpl'), 'utf-8'),
{
}
)
});
api.writeTmpFile({
path: absRuntimePath,
content: readFileSync(
@ -102,6 +112,13 @@ export default function (api) {
}
]);
api.addPluginExports(() => [
{
specifiers: ['MicroAppWithMemoHistory'],
source: absMicroAppWithMemoHistoryPath
}
]);
api.addPluginExports(() => [
{
specifiers: ['getMicroAppRouteComponent'],

View File

@ -13,15 +13,12 @@ import mergeWith from "lodash/mergeWith";
import { getMasterOptions } from "./masterOptions";
import { onBeforeRouteLeave } from "@@/core/coreExports";
let unmountPromise;
async function unmountMicroApp(microApp) {
if (microApp) {
return microApp.mountPromise.then(_microApp => {
// Now it is safe to call unmount
if(_microApp){
return _microApp.unmount()
}
})
const status = microApp.getStatus();
if(status === 'MOUNTED'){
await microApp.unmount();
}
}
return Promise.resolve();
}

View File

@ -0,0 +1,33 @@
import {
defineComponent, isRef, watch
} from 'vue';
import { MicroApp } from './MicroApp';
export const MicroAppWithMemoHistory = defineComponent({
components: {
MicroApp
},
props: {
name: {
type: String,
required: true
},
settings: Object,
lifeCycles: Object,
className: String,
url: String
},
setup(props, { attrs }) {
let microRouter;
const onRouterInit = (router) => {
microRouter = router;
microRouter.push(props.url);
};
watch(()=>props.url, () => {
microRouter.push(props.url);
});
return () => <MicroApp onRouterInit={onRouterInit} {...props} {...attrs}></MicroApp>;
}
});

View File

@ -155,6 +155,8 @@ export default function (api) {
}
});
api.addRuntimePlugin(() => `@@/${absRuntimePath}`);
api.addEntryImports(() => ({
source: `@@/${absLifeclesPath}`,
specifier:

View File

@ -1,4 +1,4 @@
import { plugin, ApplyPluginsType } from '@@/core/coreExports';
import { plugin, ApplyPluginsType, getRouter, getHistory, destroyRouter } from '@@/core/coreExports';
{{#HAS_PLUGIN_MODEL}}
import { setModelState } from './qiankunModel';
{{/HAS_PLUGIN_MODEL}}
@ -21,6 +21,10 @@ let hasMountedAtLeastOnce = false;
export default () => defer.promise;
export const clientRenderOptsStack = [];
export const history = {};
function getSlaveRuntime() {
const config = plugin.applyPlugins({
key: 'qiankun',
@ -59,6 +63,23 @@ export function genMount(mountElementId) {
}
}
// 更新 clientRender 配置
const clientRenderOpts = {
// 支持通过 props 注入 container 来限定子应用 mountElementId 的查找范围
// 避免多个子应用出现在同一主应用时出现 mount 冲突
rootElement:
props?.container?.querySelector(mountElementId) || mountElementId
};
clientRenderOptsStack.push(clientRenderOpts);
if(props.url){
history.url = props.url || '/';
}
if(props.onRouterInit){
history.onRouterInit = props.onRouterInit;
}
// 第一次 mount 会自动触发 render非第一次 mount 则需手动触发
if (hasMountedAtLeastOnce) {
const appPromise = render();
@ -87,10 +108,13 @@ export function genUpdate() {
// 子应用生命周期钩子Unmount
export function genUnmount() {
return async (props) => {
const history = getHistory();
history.destroy();
if (cacheAppPromise) {
const app = await cacheAppPromise;
app.unmount();
}
destroyRouter();
const slaveRuntime = getSlaveRuntime();
if (slaveRuntime.unmount) {
await slaveRuntime.unmount(props);

View File

@ -0,0 +1,31 @@
import { createMemoryHistory } from '@@/core/coreExports';
import qiankunRender, { clientRenderOptsStack, history } from './lifecycles';
export const render = oldRender => qiankunRender().then(oldRender);
export function modifyClientRenderOpts(memo) {
// 每次应用 render 的时候会调 modifyClientRenderOpts这时尝试从队列中取 render 的配置
const clientRenderOpts = clientRenderOptsStack.shift();
return {
...memo,
...clientRenderOpts
};
}
export function modifyHistroy(memo) {
if (history.url) {
const memoHistroy = createMemoryHistory();
memoHistroy.push(history.url)
return memoHistroy
}
return memo;
}
export function onRouterCreated({ router }) {
if(history.onRouterInit){
history.onRouterInit(router)
}
}

View File

@ -18,6 +18,7 @@ export default function (api) {
initialValue: [
// 初始化数据
'beforeRender',
// modify渲染工具
'modifyClientRenderOpts',
'rootContainer',
// app生成时触发
@ -26,6 +27,8 @@ export default function (api) {
'render',
// 修改路由
'patchRoutes',
// 修改histror
'modifyHistroy',
// 生成router时触发
'onRouterCreated'
]
@ -48,7 +51,7 @@ export default function (api) {
{
validKeys,
runtimePath
},
}
)
});
api.writeTmpFile({
@ -60,7 +63,7 @@ export default function (api) {
index,
path: winPath(plugin)
}))
},
}
)
});
});

View File

@ -293,7 +293,7 @@ export default function (api) {
api.addCoreExports(() => [
{
specifiers: ['getRoutes', 'getRouter', 'getHistory'],
specifiers: ['getRoutes', 'getRouter', 'getHistory', 'destroyRouter'],
source: absCoreFilePath
}
]);

View File

@ -20,7 +20,11 @@ export const createRouter = () => {
if (router) {
return router;
}
history = {{{ CREATE_HISTORY }}}(ROUTER_BASE)
history = plugin.applyPlugins({
key: 'modifyHistroy',
type: ApplyPluginsType.modify,
initialValue: {{{ CREATE_HISTORY }}}(ROUTER_BASE),
});
router = createVueRouter({
history,
routes: getRoutes()
@ -36,9 +40,20 @@ export const createRouter = () => {
};
export const getRouter = ()=>{
return router;
if(!router){
console.warn(`[preset-build-in] router is null`)
}
return router;
}
export const getHistory = ()=>{
return history;
if(!history){
console.warn(`[preset-build-in] history is null`)
}
return history;
}
export const destroyRouter = ()=>{
router = null;
history = null;
}