@micro-zoe/micro-app 1.0.0-beta.3 → 1.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = '1.0.0-beta.3';
1
+ const version = '1.0.0-beta.5';
2
2
  // do not use isUndefined
3
3
  const isBrowser = typeof window !== 'undefined';
4
4
  // do not use isUndefined
@@ -1668,21 +1668,33 @@ function runDynamicInlineScript(address, app, scriptInfo) {
1668
1668
  */
1669
1669
  function runCode2InlineScript(address, code, module, scriptElement, attrs, callback) {
1670
1670
  if (module) {
1671
- // module script is async, transform it to a blob for subsequent operations
1671
+ globalEnv.rawSetAttribute.call(scriptElement, 'type', 'module');
1672
1672
  if (isInlineScript(address)) {
1673
- const blob = new Blob([code], { type: 'text/javascript' });
1674
- scriptElement.src = URL.createObjectURL(blob);
1673
+ /**
1674
+ * inline module script cannot convert to blob mode
1675
+ * Issue: https://github.com/micro-zoe/micro-app/issues/805
1676
+ */
1677
+ scriptElement.textContent = code;
1675
1678
  }
1676
1679
  else {
1677
1680
  scriptElement.src = address;
1678
1681
  }
1679
- globalEnv.rawSetAttribute.call(scriptElement, 'type', 'module');
1680
1682
  if (callback) {
1681
- callback.moduleCount && callback.moduleCount--;
1683
+ const onloadHandler = () => {
1684
+ callback.moduleCount && callback.moduleCount--;
1685
+ callback(callback.moduleCount === 0);
1686
+ };
1682
1687
  /**
1683
- * module script will execute onload method only after it insert to document/iframe
1688
+ * NOTE:
1689
+ * 1. module script will execute onload method only after it insert to document/iframe
1690
+ * 2. we can't know when the inline module script onload, and we use defer to simulate, this maybe cause some problems
1684
1691
  */
1685
- scriptElement.onload = callback.bind(scriptElement, callback.moduleCount === 0);
1692
+ if (isInlineScript(address)) {
1693
+ defer(onloadHandler);
1694
+ }
1695
+ else {
1696
+ scriptElement.onload = onloadHandler;
1697
+ }
1686
1698
  }
1687
1699
  }
1688
1700
  else {
@@ -2354,6 +2366,10 @@ function patchDocument() {
2354
2366
  // const element = globalEnv.rawCreateTextNode.call(getBindTarget(this), data)
2355
2367
  // return markElement(element)
2356
2368
  // }
2369
+ rawRootDocument.prototype.createComment = function createComment(data) {
2370
+ const element = globalEnv.rawCreateComment.call(getBindTarget(this), data);
2371
+ return markElement(element);
2372
+ };
2357
2373
  // query element👇
2358
2374
  function querySelector(selectors) {
2359
2375
  var _a, _b;
@@ -2478,8 +2494,6 @@ function rejectMicroAppStyle() {
2478
2494
  }
2479
2495
 
2480
2496
  const globalEnv = {
2481
- // mark current application as base application
2482
- __MICRO_APP_BASE_APPLICATION__: true,
2483
2497
  // active sandbox count
2484
2498
  activeSandbox: 0,
2485
2499
  };
@@ -2514,6 +2528,7 @@ function initGlobalEnv() {
2514
2528
  const rawCreateElementNS = rawRootDocument.prototype.createElementNS;
2515
2529
  const rawCreateDocumentFragment = rawRootDocument.prototype.createDocumentFragment;
2516
2530
  const rawCreateTextNode = rawRootDocument.prototype.createTextNode;
2531
+ const rawCreateComment = rawRootDocument.prototype.createComment;
2517
2532
  const rawQuerySelector = rawRootDocument.prototype.querySelector;
2518
2533
  const rawQuerySelectorAll = rawRootDocument.prototype.querySelectorAll;
2519
2534
  const rawGetElementById = rawRootDocument.prototype.getElementById;
@@ -2541,6 +2556,8 @@ function initGlobalEnv() {
2541
2556
  const rawReplaceState = rawWindow.history.replaceState;
2542
2557
  const rawAddEventListener = rawRootEventTarget.prototype.addEventListener;
2543
2558
  const rawRemoveEventListener = rawRootEventTarget.prototype.removeEventListener;
2559
+ // mark current application as base application
2560
+ window.__MICRO_APP_BASE_APPLICATION__ = true;
2544
2561
  assign(globalEnv, {
2545
2562
  supportModuleScript: isSupportModuleScript(),
2546
2563
  // common global vars
@@ -2567,6 +2584,7 @@ function initGlobalEnv() {
2567
2584
  rawCreateElementNS,
2568
2585
  rawCreateDocumentFragment,
2569
2586
  rawCreateTextNode,
2587
+ rawCreateComment,
2570
2588
  rawQuerySelector,
2571
2589
  rawQuerySelectorAll,
2572
2590
  rawGetElementById,
@@ -3705,31 +3723,41 @@ function patchWindowEffect(appName, microAppWindow) {
3705
3723
 
3706
3724
  // set micro app state to origin state
3707
3725
  function setMicroState(appName, microState) {
3708
- const rawState = globalEnv.rawWindow.history.state;
3709
- const additionalState = {
3710
- microAppState: assign({}, rawState === null || rawState === void 0 ? void 0 : rawState.microAppState, {
3711
- [appName]: microState
3712
- })
3713
- };
3714
- // create new state object
3715
- return assign({}, rawState, additionalState);
3726
+ if (isMemoryRouterEnabled(appName)) {
3727
+ const rawState = globalEnv.rawWindow.history.state;
3728
+ const additionalState = {
3729
+ microAppState: assign({}, rawState === null || rawState === void 0 ? void 0 : rawState.microAppState, {
3730
+ [appName]: microState
3731
+ })
3732
+ };
3733
+ // create new state object
3734
+ return assign({}, rawState, additionalState);
3735
+ }
3736
+ return microState;
3716
3737
  }
3717
3738
  // delete micro app state form origin state
3718
3739
  function removeMicroState(appName, rawState) {
3719
- if (isPlainObject(rawState === null || rawState === void 0 ? void 0 : rawState.microAppState)) {
3720
- if (!isUndefined(rawState.microAppState[appName])) {
3721
- delete rawState.microAppState[appName];
3722
- }
3723
- if (!Object.keys(rawState.microAppState).length) {
3724
- delete rawState.microAppState;
3740
+ if (isMemoryRouterEnabled(appName)) {
3741
+ if (isPlainObject(rawState === null || rawState === void 0 ? void 0 : rawState.microAppState)) {
3742
+ if (!isUndefined(rawState.microAppState[appName])) {
3743
+ delete rawState.microAppState[appName];
3744
+ }
3745
+ if (!Object.keys(rawState.microAppState).length) {
3746
+ delete rawState.microAppState;
3747
+ }
3725
3748
  }
3749
+ return assign({}, rawState);
3726
3750
  }
3727
- return assign({}, rawState);
3751
+ return rawState;
3728
3752
  }
3729
3753
  // get micro app state form origin state
3730
3754
  function getMicroState(appName) {
3731
- var _a, _b;
3732
- return ((_b = (_a = globalEnv.rawWindow.history.state) === null || _a === void 0 ? void 0 : _a.microAppState) === null || _b === void 0 ? void 0 : _b[appName]) || null;
3755
+ var _a;
3756
+ const rawState = globalEnv.rawWindow.history.state;
3757
+ if (isMemoryRouterEnabled(appName)) {
3758
+ return ((_a = rawState === null || rawState === void 0 ? void 0 : rawState.microAppState) === null || _a === void 0 ? void 0 : _a[appName]) || null;
3759
+ }
3760
+ return rawState;
3733
3761
  }
3734
3762
  const ENC_AD_RE = /&/g; // %M1
3735
3763
  const ENC_EQ_RE = /=/g; // %M2
@@ -3767,53 +3795,61 @@ function formatQueryAppName(appName) {
3767
3795
  function getMicroPathFromURL(appName) {
3768
3796
  var _a, _b;
3769
3797
  const rawLocation = globalEnv.rawWindow.location;
3770
- const queryObject = getQueryObjectFromURL(rawLocation.search, rawLocation.hash);
3771
- const microPath = ((_a = queryObject.hashQuery) === null || _a === void 0 ? void 0 : _a[formatQueryAppName(appName)]) || ((_b = queryObject.searchQuery) === null || _b === void 0 ? void 0 : _b[formatQueryAppName(appName)]);
3772
- return isString(microPath) ? decodeMicroPath(microPath) : null;
3798
+ if (isMemoryRouterEnabled(appName)) {
3799
+ const queryObject = getQueryObjectFromURL(rawLocation.search, rawLocation.hash);
3800
+ const microPath = ((_a = queryObject.hashQuery) === null || _a === void 0 ? void 0 : _a[formatQueryAppName(appName)]) || ((_b = queryObject.searchQuery) === null || _b === void 0 ? void 0 : _b[formatQueryAppName(appName)]);
3801
+ return isString(microPath) ? decodeMicroPath(microPath) : null;
3802
+ }
3803
+ return rawLocation.pathname + rawLocation.search + rawLocation.hash;
3773
3804
  }
3774
3805
  /**
3775
3806
  * Attach child app fullPath to browser url
3776
3807
  * @param appName app.name
3777
- * @param microLocation location of child app
3808
+ * @param targetLocation location of child app or rawLocation of window
3778
3809
  */
3779
- function setMicroPathToURL(appName, microLocation) {
3780
- let { pathname, search, hash } = globalEnv.rawWindow.location;
3781
- const queryObject = getQueryObjectFromURL(search, hash);
3782
- const encodedMicroPath = encodeMicroPath(microLocation.pathname +
3783
- microLocation.search +
3784
- microLocation.hash);
3785
- /**
3786
- * Is parent is hash router
3787
- * In fact, this is not true. It just means that the parameter is added to the hash
3788
- */
3810
+ function setMicroPathToURL(appName, targetLocation) {
3811
+ const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
3789
3812
  let isAttach2Hash = false;
3790
- // If hash exists and search does not exist, it is considered as a hash route
3791
- if (hash && !search) {
3792
- isAttach2Hash = true;
3793
- if (queryObject.hashQuery) {
3794
- queryObject.hashQuery[formatQueryAppName(appName)] = encodedMicroPath;
3795
- }
3796
- else {
3797
- queryObject.hashQuery = {
3798
- [formatQueryAppName(appName)]: encodedMicroPath
3799
- };
3800
- }
3801
- const baseHash = hash.includes('?') ? hash.slice(0, hash.indexOf('?') + 1) : hash + '?';
3802
- hash = baseHash + stringifyQuery(queryObject.hashQuery);
3803
- }
3804
- else {
3805
- if (queryObject.searchQuery) {
3806
- queryObject.searchQuery[formatQueryAppName(appName)] = encodedMicroPath;
3813
+ if (isMemoryRouterEnabled(appName)) {
3814
+ let { pathname, search, hash } = globalEnv.rawWindow.location;
3815
+ const queryObject = getQueryObjectFromURL(search, hash);
3816
+ const encodedMicroPath = encodeMicroPath(targetFullPath);
3817
+ /**
3818
+ * Is parent is hash router
3819
+ * In fact, this is not true. It just means that the parameter is added to the hash
3820
+ */
3821
+ // If hash exists and search does not exist, it is considered as a hash route
3822
+ if (hash && !search) {
3823
+ isAttach2Hash = true;
3824
+ if (queryObject.hashQuery) {
3825
+ queryObject.hashQuery[formatQueryAppName(appName)] = encodedMicroPath;
3826
+ }
3827
+ else {
3828
+ queryObject.hashQuery = {
3829
+ [formatQueryAppName(appName)]: encodedMicroPath
3830
+ };
3831
+ }
3832
+ const baseHash = hash.includes('?') ? hash.slice(0, hash.indexOf('?') + 1) : hash + '?';
3833
+ hash = baseHash + stringifyQuery(queryObject.hashQuery);
3807
3834
  }
3808
3835
  else {
3809
- queryObject.searchQuery = {
3810
- [formatQueryAppName(appName)]: encodedMicroPath
3811
- };
3836
+ if (queryObject.searchQuery) {
3837
+ queryObject.searchQuery[formatQueryAppName(appName)] = encodedMicroPath;
3838
+ }
3839
+ else {
3840
+ queryObject.searchQuery = {
3841
+ [formatQueryAppName(appName)]: encodedMicroPath
3842
+ };
3843
+ }
3844
+ search = '?' + stringifyQuery(queryObject.searchQuery);
3812
3845
  }
3813
- search = '?' + stringifyQuery(queryObject.searchQuery);
3846
+ return {
3847
+ fullPath: pathname + search + hash,
3848
+ isAttach2Hash,
3849
+ };
3814
3850
  }
3815
3851
  return {
3816
- fullPath: pathname + search + hash,
3852
+ fullPath: targetFullPath,
3817
3853
  isAttach2Hash,
3818
3854
  };
3819
3855
  }
@@ -3825,18 +3861,20 @@ function setMicroPathToURL(appName, microLocation) {
3825
3861
  function removeMicroPathFromURL(appName, targetLocation) {
3826
3862
  var _a, _b, _c, _d;
3827
3863
  let { pathname, search, hash } = targetLocation || globalEnv.rawWindow.location;
3828
- const queryObject = getQueryObjectFromURL(search, hash);
3829
3864
  let isAttach2Hash = false;
3830
- if ((_a = queryObject.hashQuery) === null || _a === void 0 ? void 0 : _a[formatQueryAppName(appName)]) {
3831
- isAttach2Hash = true;
3832
- (_b = queryObject.hashQuery) === null || _b === void 0 ? true : delete _b[formatQueryAppName(appName)];
3833
- const hashQueryStr = stringifyQuery(queryObject.hashQuery);
3834
- hash = hash.slice(0, hash.indexOf('?') + Number(Boolean(hashQueryStr))) + hashQueryStr;
3835
- }
3836
- else if ((_c = queryObject.searchQuery) === null || _c === void 0 ? void 0 : _c[formatQueryAppName(appName)]) {
3837
- (_d = queryObject.searchQuery) === null || _d === void 0 ? true : delete _d[formatQueryAppName(appName)];
3838
- const searchQueryStr = stringifyQuery(queryObject.searchQuery);
3839
- search = searchQueryStr ? '?' + searchQueryStr : '';
3865
+ if (isMemoryRouterEnabled(appName)) {
3866
+ const queryObject = getQueryObjectFromURL(search, hash);
3867
+ if ((_a = queryObject.hashQuery) === null || _a === void 0 ? void 0 : _a[formatQueryAppName(appName)]) {
3868
+ isAttach2Hash = true;
3869
+ (_b = queryObject.hashQuery) === null || _b === void 0 ? true : delete _b[formatQueryAppName(appName)];
3870
+ const hashQueryStr = stringifyQuery(queryObject.hashQuery);
3871
+ hash = hash.slice(0, hash.indexOf('?') + Number(Boolean(hashQueryStr))) + hashQueryStr;
3872
+ }
3873
+ else if ((_c = queryObject.searchQuery) === null || _c === void 0 ? void 0 : _c[formatQueryAppName(appName)]) {
3874
+ (_d = queryObject.searchQuery) === null || _d === void 0 ? true : delete _d[formatQueryAppName(appName)];
3875
+ const searchQueryStr = stringifyQuery(queryObject.searchQuery);
3876
+ search = searchQueryStr ? '?' + searchQueryStr : '';
3877
+ }
3840
3878
  }
3841
3879
  return {
3842
3880
  fullPath: pathname + search + hash,
@@ -3876,7 +3914,23 @@ function getNoHashMicroPathFromURL(appName, baseUrl) {
3876
3914
  */
3877
3915
  function isEffectiveApp(appName) {
3878
3916
  const app = appInstanceMap.get(appName);
3879
- return !!(app && !app.isPrefetch && !app.isHidden());
3917
+ /**
3918
+ * !!(app && !app.isPrefetch && !app.isHidden())
3919
+ * 隐藏的keep-alive应用暂时不作为无效应用,原因如下
3920
+ * 1、隐藏后才执行去除浏览器上的微应用的路由信息的操作,导致微应用的路由信息无法去除
3921
+ * 2、如果保持隐藏应用内部正常跳转,阻止同步路由信息到浏览器,这样理论上是好的,但是对于location跳转改如何处理?location跳转是基于修改浏览器地址后发送popstate事件实现的,所以应该是在隐藏后不支持通过location进行跳转
3922
+ */
3923
+ return !!(app && !app.isPrefetch);
3924
+ }
3925
+ /**
3926
+ * Determine whether the app has enabled memory-router
3927
+ * NOTE:
3928
+ * 1. if sandbox disabled, memory-router is disabled
3929
+ * 2. if app not exist, memory-router is disabled
3930
+ */
3931
+ function isMemoryRouterEnabled(appName) {
3932
+ const app = appInstanceMap.get(appName);
3933
+ return !!(app && app.sandBox && app.useMemoryRouter);
3880
3934
  }
3881
3935
 
3882
3936
  /**
@@ -3899,26 +3953,7 @@ function addHistoryListener(appName) {
3899
3953
  excludePreRender: true,
3900
3954
  }).includes(appName) &&
3901
3955
  !e.onlyForBrowser) {
3902
- const microPath = getMicroPathFromURL(appName);
3903
- const app = appInstanceMap.get(appName);
3904
- const proxyWindow = app.sandBox.proxyWindow;
3905
- const microAppWindow = app.sandBox.microAppWindow;
3906
- let isHashChange = false;
3907
- // for hashChangeEvent
3908
- const oldHref = proxyWindow.location.href;
3909
- // Do not attach micro state to url when microPath is empty
3910
- if (microPath) {
3911
- const oldHash = proxyWindow.location.hash;
3912
- updateMicroLocation(appName, microPath, microAppWindow.location);
3913
- isHashChange = proxyWindow.location.hash !== oldHash;
3914
- }
3915
- // dispatch formatted popStateEvent to child
3916
- dispatchPopStateEventToMicroApp(appName, proxyWindow, microAppWindow);
3917
- // dispatch formatted hashChangeEvent to child when hash change
3918
- if (isHashChange)
3919
- dispatchHashChangeEventToMicroApp(appName, proxyWindow, microAppWindow, oldHref);
3920
- // clear element scope before trigger event of next app
3921
- removeDomScope();
3956
+ updateMicroLocationWithEvent(appName, getMicroPathFromURL(appName));
3922
3957
  }
3923
3958
  };
3924
3959
  rawWindow.addEventListener('popstate', popStateHandler);
@@ -3926,6 +3961,35 @@ function addHistoryListener(appName) {
3926
3961
  rawWindow.removeEventListener('popstate', popStateHandler);
3927
3962
  };
3928
3963
  }
3964
+ /**
3965
+ * Effect: use to trigger child app jump
3966
+ * Actions:
3967
+ * 1. update microLocation with target path
3968
+ * 2. dispatch popStateEvent & hashChangeEvent
3969
+ * @param appName app name
3970
+ * @param targetFullPath target path of child app
3971
+ */
3972
+ function updateMicroLocationWithEvent(appName, targetFullPath) {
3973
+ const app = appInstanceMap.get(appName);
3974
+ const proxyWindow = app.sandBox.proxyWindow;
3975
+ const microAppWindow = app.sandBox.microAppWindow;
3976
+ let isHashChange = false;
3977
+ // for hashChangeEvent
3978
+ const oldHref = proxyWindow.location.href;
3979
+ // Do not attach micro state to url when targetFullPath is empty
3980
+ if (targetFullPath) {
3981
+ const oldHash = proxyWindow.location.hash;
3982
+ updateMicroLocation(appName, targetFullPath, microAppWindow.location);
3983
+ isHashChange = proxyWindow.location.hash !== oldHash;
3984
+ }
3985
+ // dispatch formatted popStateEvent to child
3986
+ dispatchPopStateEventToMicroApp(appName, proxyWindow, microAppWindow);
3987
+ // dispatch formatted hashChangeEvent to child when hash change
3988
+ if (isHashChange)
3989
+ dispatchHashChangeEventToMicroApp(appName, proxyWindow, microAppWindow, oldHref);
3990
+ // clear element scope before trigger event of next app
3991
+ removeDomScope();
3992
+ }
3929
3993
  /**
3930
3994
  * dispatch formatted popstate event to microApp
3931
3995
  * @param appName app name
@@ -4088,6 +4152,8 @@ function nativeHistoryNavigate(appName, methodName, fullPath, state = null, titl
4088
4152
  * 2. proxyHistory.pushState/replaceState with limited popstateEvent
4089
4153
  * 3. api microApp.router.push/replace
4090
4154
  * 4. proxyLocation.hash = xxx
4155
+ * NOTE:
4156
+ * 1. hidden keep-alive app can jump internally, but will not synchronize to browser
4091
4157
  * @param appName app.name
4092
4158
  * @param methodName pushState/replaceState
4093
4159
  * @param result result of add/remove microApp path on browser url
@@ -4103,8 +4169,10 @@ function navigateWithNativeEvent(appName, methodName, result, onlyForBrowser, st
4103
4169
  const oldHref = result.isAttach2Hash && oldFullPath !== result.fullPath ? rawLocation.href : null;
4104
4170
  // navigate with native history method
4105
4171
  nativeHistoryNavigate(appName, methodName, result.fullPath, state, title);
4106
- if (oldFullPath !== result.fullPath)
4172
+ // TODO: 如果所有模式统一发送popstate事件,则isMemoryRouterEnabled(appName)要去掉
4173
+ if (oldFullPath !== result.fullPath && isMemoryRouterEnabled(appName)) {
4107
4174
  dispatchNativeEvent(appName, onlyForBrowser, oldHref);
4175
+ }
4108
4176
  }
4109
4177
  }
4110
4178
  /**
@@ -4149,8 +4217,8 @@ function reWriteHistoryMethod(method) {
4149
4217
  excludeHiddenApp: true,
4150
4218
  excludePreRender: true,
4151
4219
  }).forEach(appName => {
4152
- const app = appInstanceMap.get(appName);
4153
- if (app.sandBox && app.useMemoryRouter && !getMicroPathFromURL(appName)) {
4220
+ if (isMemoryRouterEnabled(appName) && !getMicroPathFromURL(appName)) {
4221
+ const app = appInstanceMap.get(appName);
4154
4222
  attachRouteToBrowserURL(appName, setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
4155
4223
  }
4156
4224
  });
@@ -4199,12 +4267,14 @@ function createRouterApi() {
4199
4267
  return function (to) {
4200
4268
  const appName = formatAppName(to.name);
4201
4269
  if (appName && isString(to.path)) {
4202
- const app = appInstanceMap.get(appName);
4203
- if (app && (!app.sandBox || !app.useMemoryRouter)) {
4204
- return logError(`navigation failed, memory router of app ${appName} is closed`);
4205
- }
4206
- // active apps, include hidden keep-alive app
4207
- if (getActiveApps({ excludePreRender: true }).includes(appName)) {
4270
+ /**
4271
+ * active apps, exclude prerender app or hidden keep-alive app
4272
+ * NOTE:
4273
+ * 1. prerender app or hidden keep-alive app clear and record popstate event, so we cannot control app jump through the API
4274
+ * 2. disable memory-router
4275
+ */
4276
+ if (getActiveApps({ excludeHiddenApp: true, excludePreRender: true }).includes(appName)) {
4277
+ const app = appInstanceMap.get(appName);
4208
4278
  const microLocation = app.sandBox.proxyWindow.location;
4209
4279
  const targetLocation = createURL(to.path, microLocation.href);
4210
4280
  // Only get path data, even if the origin is different from microApp
@@ -4213,20 +4283,48 @@ function createRouterApi() {
4213
4283
  if (currentFullPath !== targetFullPath || getMicroPathFromURL(appName) !== targetFullPath) {
4214
4284
  const methodName = (replace && to.replace !== false) || to.replace === true ? 'replaceState' : 'pushState';
4215
4285
  navigateWithRawHistory(appName, methodName, targetLocation, to.state);
4286
+ /**
4287
+ * TODO:
4288
+ * 1. 关闭虚拟路由的跳转地址不同:baseRoute + 子应用地址,文档中要说明
4289
+ * 2. 关闭虚拟路由时跳转方式不同:1、基座跳转但不发送popstate事件 2、控制子应用更新location,内部发送popstate事件。
4290
+ * 补充:
4291
+ * 核心思路:减小对基座的影响(就是子应用跳转不向基座发送popstate事件,其他操作一致),但这是必要的吗,只是多了一个触发popstate的操作
4292
+ * 未来的思路有两种:
4293
+ * 1、减少对基座的影响,主要是解决vue循环刷新的问题
4294
+ * 2、全局发送popstate事件,解决主、子都是vue3的冲突问题
4295
+ * 两者选一个吧,如果选2,则下面这两行代码可以去掉
4296
+ * 要不这样吧,history和search模式采用2,这样可以解决vue3的问题,custom采用1,避免vue循环刷新的问题,这样在用户出现问题时各有解决方案。但反过来说,每种方案又分别导致另外的问题,不统一,导致复杂度增高
4297
+ * 如果关闭虚拟路由,同时发送popstate事件还是无法解决vue3的问题(毕竟history.state理论上还是会冲突),那么就没必要发送popstate事件了。
4298
+ * 。。。。先这样吧
4299
+ */
4300
+ if (!isMemoryRouterEnabled(appName)) {
4301
+ updateMicroLocationWithEvent(appName, targetFullPath);
4302
+ }
4216
4303
  }
4217
4304
  }
4218
4305
  else {
4219
- /**
4220
- * app not exit or unmounted, update browser URL with replaceState
4221
- * use base app location.origin as baseURL
4222
- */
4223
- const rawLocation = globalEnv.rawWindow.location;
4224
- const targetLocation = createURL(to.path, rawLocation.origin);
4225
- const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
4226
- if (getMicroPathFromURL(appName) !== targetFullPath) {
4227
- navigateWithRawHistory(appName, to.replace === false ? 'pushState' : 'replaceState', targetLocation, to.state);
4228
- }
4306
+ logWarn('navigation failed, app does not exist or is inactive');
4229
4307
  }
4308
+ // /**
4309
+ // * app not exit or unmounted, update browser URL with replaceState
4310
+ // * use base app location.origin as baseURL
4311
+ // * 应用不存在或已卸载,依然使用replaceState来更新浏览器地址 -- 不合理
4312
+ // */
4313
+ // /**
4314
+ // * TODO: 应用还没渲染或已经卸载最好不要支持跳转了,我知道这是因为解决一些特殊场景,但这么做是非常反直觉的
4315
+ // * 并且在新版本中有多种路由模式,如果应用不存在,我们根本无法知道是哪种模式,那么这里的操作就无意义了。
4316
+ // */
4317
+ // const rawLocation = globalEnv.rawWindow.location
4318
+ // const targetLocation = createURL(to.path, rawLocation.origin)
4319
+ // const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash
4320
+ // if (getMicroPathFromURL(appName) !== targetFullPath) {
4321
+ // navigateWithRawHistory(
4322
+ // appName,
4323
+ // to.replace === false ? 'pushState' : 'replaceState',
4324
+ // targetLocation,
4325
+ // to.state,
4326
+ // )
4327
+ // }
4230
4328
  }
4231
4329
  else {
4232
4330
  logError(`navigation failed, name & path are required when use router.${replace ? 'replace' : 'push'}`);
@@ -4286,8 +4384,8 @@ function createRouterApi() {
4286
4384
  * 2. useMemoryRouter is false
4287
4385
  */
4288
4386
  function commonHandlerForAttachToURL(appName) {
4289
- const app = appInstanceMap.get(appName);
4290
- if (app.sandBox && app.useMemoryRouter) {
4387
+ if (isMemoryRouterEnabled(appName)) {
4388
+ const app = appInstanceMap.get(appName);
4291
4389
  attachRouteToBrowserURL(appName, setMicroPathToURL(appName, app.sandBox.proxyWindow.location), setMicroState(appName, getMicroState(appName)));
4292
4390
  }
4293
4391
  }
@@ -4539,37 +4637,40 @@ function createMicroLocation(appName, url, microAppWindow, childStaticLocation,
4539
4637
  // Even if the origin is the same, developers still have the possibility of want to jump to a new page
4540
4638
  if (targetLocation.origin === proxyLocation.origin) {
4541
4639
  const setMicroPathResult = setMicroPathToURL(appName, targetLocation);
4542
- /**
4543
- * change hash with location.href will not trigger the browser reload
4544
- * so we use pushState & reload to imitate href behavior
4545
- * NOTE:
4546
- * 1. if child app only change hash, it should not trigger browser reload
4547
- * 2. if address is same and has hash, it should not add route stack
4548
- */
4549
- if (targetLocation.pathname === proxyLocation.pathname &&
4550
- targetLocation.search === proxyLocation.search) {
4551
- let oldHref = null;
4552
- if (targetLocation.hash !== proxyLocation.hash) {
4553
- if (setMicroPathResult.isAttach2Hash)
4554
- oldHref = rawLocation.href;
4555
- nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
4556
- }
4557
- if (targetLocation.hash) {
4558
- dispatchNativeEvent(appName, false, oldHref);
4640
+ // if disable memory-router, navigate directly through rawLocation
4641
+ if (isMemoryRouterEnabled(appName)) {
4642
+ /**
4643
+ * change hash with location.href will not trigger the browser reload
4644
+ * so we use pushState & reload to imitate href behavior
4645
+ * NOTE:
4646
+ * 1. if child app only change hash, it should not trigger browser reload
4647
+ * 2. if address is same and has hash, it should not add route stack
4648
+ */
4649
+ if (targetLocation.pathname === proxyLocation.pathname &&
4650
+ targetLocation.search === proxyLocation.search) {
4651
+ let oldHref = null;
4652
+ if (targetLocation.hash !== proxyLocation.hash) {
4653
+ if (setMicroPathResult.isAttach2Hash)
4654
+ oldHref = rawLocation.href;
4655
+ nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
4656
+ }
4657
+ if (targetLocation.hash) {
4658
+ dispatchNativeEvent(appName, false, oldHref);
4659
+ }
4660
+ else {
4661
+ reload();
4662
+ }
4663
+ return void 0;
4664
+ /**
4665
+ * when baseApp is hash router, address change of child can not reload browser
4666
+ * so we imitate behavior of browser (reload) manually
4667
+ */
4559
4668
  }
4560
- else {
4669
+ else if (setMicroPathResult.isAttach2Hash) {
4670
+ nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
4561
4671
  reload();
4672
+ return void 0;
4562
4673
  }
4563
- return void 0;
4564
- /**
4565
- * when baseApp is hash router, address change of child can not reload browser
4566
- * so we imitate behavior of browser (reload) manually
4567
- */
4568
- }
4569
- else if (setMicroPathResult.isAttach2Hash) {
4570
- nativeHistoryNavigate(appName, methodName, setMicroPathResult.fullPath);
4571
- reload();
4572
- return void 0;
4573
4674
  }
4574
4675
  return setMicroPathResult.fullPath;
4575
4676
  }
@@ -4661,19 +4762,34 @@ function createMicroLocation(appName, url, microAppWindow, childStaticLocation,
4661
4762
  }
4662
4763
  }
4663
4764
  else if (key === 'pathname') {
4664
- const targetPath = ('/' + value).replace(/^\/+/, '/') + proxyLocation.search + proxyLocation.hash;
4665
- handleForPathNameAndSearch(targetPath, 'pathname');
4765
+ if (isMemoryRouterEnabled(appName)) {
4766
+ const targetPath = ('/' + value).replace(/^\/+/, '/') + proxyLocation.search + proxyLocation.hash;
4767
+ handleForPathNameAndSearch(targetPath, 'pathname');
4768
+ }
4769
+ else {
4770
+ rawLocation.pathname = value;
4771
+ }
4666
4772
  }
4667
4773
  else if (key === 'search') {
4668
- const targetPath = proxyLocation.pathname + ('?' + value).replace(/^\?+/, '?') + proxyLocation.hash;
4669
- handleForPathNameAndSearch(targetPath, 'search');
4774
+ if (isMemoryRouterEnabled(appName)) {
4775
+ const targetPath = proxyLocation.pathname + ('?' + value).replace(/^\?+/, '?') + proxyLocation.hash;
4776
+ handleForPathNameAndSearch(targetPath, 'search');
4777
+ }
4778
+ else {
4779
+ rawLocation.search = value;
4780
+ }
4670
4781
  }
4671
4782
  else if (key === 'hash') {
4672
- const targetPath = proxyLocation.pathname + proxyLocation.search + ('#' + value).replace(/^#+/, '#');
4673
- const targetLocation = createURL(targetPath, url);
4674
- // The same hash will not trigger popStateEvent
4675
- if (targetLocation.hash !== proxyLocation.hash) {
4676
- navigateWithNativeEvent(appName, 'pushState', setMicroPathToURL(appName, targetLocation), false);
4783
+ if (isMemoryRouterEnabled(appName)) {
4784
+ const targetPath = proxyLocation.pathname + proxyLocation.search + ('#' + value).replace(/^#+/, '#');
4785
+ const targetLocation = createURL(targetPath, url);
4786
+ // The same hash will not trigger popStateEvent
4787
+ if (targetLocation.hash !== proxyLocation.hash) {
4788
+ navigateWithNativeEvent(appName, 'pushState', setMicroPathToURL(appName, targetLocation), false);
4789
+ }
4790
+ }
4791
+ else {
4792
+ rawLocation.hash = value;
4677
4793
  }
4678
4794
  }
4679
4795
  else {
@@ -4718,6 +4834,7 @@ function updateMicroLocation(appName, path, microLocation, type) {
4718
4834
  var _a;
4719
4835
  // record old values of microLocation to `from`
4720
4836
  const from = createGuardLocation(appName, microLocation);
4837
+ // if is iframeSandbox, microLocation muse be rawLocation of iframe, not proxyLocation
4721
4838
  const newLocation = createURL(path, microLocation.href);
4722
4839
  if (isIframeSandbox(appName)) {
4723
4840
  const microAppWindow = appInstanceMap.get(appName).sandBox.microAppWindow;
@@ -4736,6 +4853,15 @@ function updateMicroLocation(appName, path, microLocation, type) {
4736
4853
  }
4737
4854
  }
4738
4855
 
4856
+ /**
4857
+ * TODO: 关于关闭虚拟路由系统的临时笔记
4858
+ * 1. with沙箱关闭虚拟路由最好和iframe保持一致
4859
+ * 2. default-page无法使用,但是用基座的地址可以实现一样的效果
4860
+ * 3. keep-router-state功能失效,因为始终为true
4861
+ * 4. 基座控制子应用跳转地址改变,正确的值为:baseRoute + 子应用地址,这要在文档中说明,否则很容易出错,确实也很难理解
4862
+ * 5. 是否需要发送popstate事件,为了减小对基座的影响,现在不发送
4863
+ * 6. 关闭后导致的vue3路由冲突问题需要在文档中明确指出(2处:在关闭虚拟路由系统的配置那里着重说明,在vue常见问题中说明)
4864
+ */
4739
4865
  /**
4740
4866
  * The router system has two operations: read and write
4741
4867
  * Read through location and write through history & location
@@ -4767,7 +4893,9 @@ function initRouteStateWithURL(appName, microLocation, defaultPage) {
4767
4893
  }
4768
4894
  /**
4769
4895
  * initialize browser information according to microLocation
4770
- * called on sandbox.start or reshow of keep-alive app
4896
+ * Scenes:
4897
+ * 1. sandbox.start
4898
+ * 2. reshow of keep-alive app
4771
4899
  */
4772
4900
  function updateBrowserURLWithLocation(appName, microLocation, defaultPage) {
4773
4901
  // update microLocation with defaultPage
@@ -4790,14 +4918,14 @@ function clearRouteStateFromURL(appName, url, microLocation, keepRouteState) {
4790
4918
  const { pathname, search, hash } = createURL(url);
4791
4919
  updateMicroLocation(appName, pathname + search + hash, microLocation, 'prevent');
4792
4920
  }
4793
- removeStateAndPathFromBrowser(appName);
4921
+ removePathFromBrowser(appName);
4794
4922
  clearRouterWhenUnmount(appName);
4795
4923
  }
4796
4924
  /**
4797
4925
  * remove microState from history.state and remove microPath from browserURL
4798
4926
  * called on sandbox.stop or hidden of keep-alive app
4799
4927
  */
4800
- function removeStateAndPathFromBrowser(appName) {
4928
+ function removePathFromBrowser(appName) {
4801
4929
  attachRouteToBrowserURL(appName, removeMicroPathFromURL(appName), removeMicroState(appName, globalEnv.rawWindow.history.state));
4802
4930
  }
4803
4931
 
@@ -4941,6 +5069,7 @@ class WithSandBox {
4941
5069
  if (this.active)
4942
5070
  return;
4943
5071
  this.active = true;
5072
+ // TODO: with沙箱关闭虚拟路由保持和iframe一致
4944
5073
  if (useMemoryRouter) {
4945
5074
  if (isUndefined(this.microAppWindow.location)) {
4946
5075
  this.setMicroAppRouter(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.__MICRO_APP_URL__, this.microAppWindow);
@@ -4977,16 +5106,18 @@ class WithSandBox {
4977
5106
  * @param keepRouteState prevent reset route
4978
5107
  * @param destroy completely destroy, delete cache resources
4979
5108
  * @param clearData clear data from base app
5109
+ * @param useMemoryRouter use virtual router
4980
5110
  */
4981
- stop({ umdMode, keepRouteState, destroy, clearData, }) {
5111
+ stop({ umdMode, keepRouteState, destroy, clearData, useMemoryRouter, }) {
5112
+ var _a;
4982
5113
  if (!this.active)
4983
5114
  return;
4984
5115
  this.recordAndReleaseEffect({ umdMode, clearData, destroy }, !umdMode || destroy);
4985
- if (this.removeHistoryListener) {
5116
+ if (useMemoryRouter) {
4986
5117
  this.clearRouteState(keepRouteState);
4987
- // release listener of popstate
4988
- this.removeHistoryListener();
4989
5118
  }
5119
+ // release listener of popstate for child app
5120
+ (_a = this.removeHistoryListener) === null || _a === void 0 ? void 0 : _a.call(this);
4990
5121
  /**
4991
5122
  * NOTE:
4992
5123
  * 1. injectedKeys and escapeKeys must be placed at the back
@@ -5428,7 +5559,7 @@ class WithSandBox {
5428
5559
  updateBrowserURLWithLocation(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.location);
5429
5560
  }
5430
5561
  removeRouteInfoForKeepAliveApp() {
5431
- removeStateAndPathFromBrowser(this.microAppWindow.__MICRO_APP_NAME__);
5562
+ removePathFromBrowser(this.microAppWindow.__MICRO_APP_NAME__);
5432
5563
  }
5433
5564
  /**
5434
5565
  * Format all html elements when init
@@ -5628,6 +5759,7 @@ function patchDocumentPrototype(appName, microAppWindow) {
5628
5759
  const microDocument = microAppWindow.document;
5629
5760
  const rawMicroCreateElement = microRootDocument.prototype.createElement;
5630
5761
  const rawMicroCreateTextNode = microRootDocument.prototype.createTextNode;
5762
+ const rawMicroCreateComment = microRootDocument.prototype.createComment;
5631
5763
  const rawMicroQuerySelector = microRootDocument.prototype.querySelector;
5632
5764
  const rawMicroQuerySelectorAll = microRootDocument.prototype.querySelectorAll;
5633
5765
  const rawMicroGetElementById = microRootDocument.prototype.getElementById;
@@ -5642,6 +5774,10 @@ function patchDocumentPrototype(appName, microAppWindow) {
5642
5774
  const element = rawMicroCreateTextNode.call(this, data);
5643
5775
  return updateElementInfo(element, appName);
5644
5776
  };
5777
+ microRootDocument.prototype.createComment = function createComment(data) {
5778
+ const element = rawMicroCreateComment.call(this, data);
5779
+ return updateElementInfo(element, appName);
5780
+ };
5645
5781
  function getDefaultRawTarget(target) {
5646
5782
  return microDocument !== target ? target : rawDocument;
5647
5783
  }
@@ -6206,12 +6342,29 @@ class IframeSandbox {
6206
6342
  if (this.active)
6207
6343
  return;
6208
6344
  this.active = true;
6209
- if (useMemoryRouter) {
6210
- this.initRouteState(defaultPage);
6211
- // unique listener of popstate event for sub app
6212
- this.removeHistoryListener = addHistoryListener(this.microAppWindow.__MICRO_APP_NAME__);
6213
- }
6214
- else {
6345
+ /**
6346
+ * Sync router info to iframe when exec sandbox.start with disable or enable memory-router
6347
+ * e.g.:
6348
+ * vue-router@4.x get target path by remove the base section from rawLocation.pathname
6349
+ * code: window.location.pathname.slice(base.length) || '/'; (base is baseroute)
6350
+ * NOTE:
6351
+ * 1. iframe router and browser router are separated, we should update iframe router manually
6352
+ * 2. withSandbox location is browser location when disable memory-router, so no need to do anything
6353
+ */
6354
+ /**
6355
+ * TODO:
6356
+ * 做一些记录:
6357
+ * 1. iframe关闭虚拟路由系统后,default-page无法使用,推荐用户直接使用浏览器地址控制首页渲染
6358
+ * 补充:keep-router-state 也无法配置,因为keep-router-state一定为true。
6359
+ * 2. 导航拦截、current.route 可以正常使用
6360
+ * 3. 可以正常控制子应用跳转,方式还是自上而下(也可以是子应用内部跳转,这种方式更好一点,减小对基座的影响,不会导致vue的循环刷新)
6361
+ * 4. 关闭虚拟路由以后会对应 route-mode='custom' 模式,包括with沙箱也会这么做
6362
+ * 5. 关闭虚拟路由是指尽可能模式没有虚拟路由的情况,子应用直接获取浏览器location和history,控制浏览器跳转
6363
+ */
6364
+ this.initRouteState(defaultPage);
6365
+ // unique listener of popstate event for child app
6366
+ this.removeHistoryListener = addHistoryListener(this.microAppWindow.__MICRO_APP_NAME__);
6367
+ if (!useMemoryRouter) {
6215
6368
  this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseroute;
6216
6369
  }
6217
6370
  /**
@@ -6227,15 +6380,15 @@ class IframeSandbox {
6227
6380
  }
6228
6381
  if (++IframeSandbox.activeCount === 1) ;
6229
6382
  }
6230
- stop({ umdMode, keepRouteState, destroy, clearData, }) {
6383
+ stop({ umdMode, keepRouteState, destroy, clearData, useMemoryRouter, }) {
6384
+ var _a;
6231
6385
  if (!this.active)
6232
6386
  return;
6233
6387
  this.recordAndReleaseEffect({ clearData }, !umdMode || destroy);
6234
- if (this.removeHistoryListener) {
6235
- this.clearRouteState(keepRouteState);
6236
- // release listener of popstate
6237
- this.removeHistoryListener();
6238
- }
6388
+ // if keep-route-state is true or disable memory-router, preserve microLocation state
6389
+ this.clearRouteState(keepRouteState || !useMemoryRouter);
6390
+ // release listener of popstate for child app
6391
+ (_a = this.removeHistoryListener) === null || _a === void 0 ? void 0 : _a.call(this);
6239
6392
  if (!umdMode || destroy) {
6240
6393
  this.deleteIframeElement();
6241
6394
  this.escapeKeys.forEach((key) => {
@@ -6409,6 +6562,7 @@ class IframeSandbox {
6409
6562
  }
6410
6563
  createProxyWindow(microAppWindow) {
6411
6564
  const rawWindow = globalEnv.rawWindow;
6565
+ const customProperties = [];
6412
6566
  return new Proxy(microAppWindow, {
6413
6567
  get: (target, key) => {
6414
6568
  if (key === 'location') {
@@ -6417,6 +6571,9 @@ class IframeSandbox {
6417
6571
  if (globalPropertyList.includes(key.toString())) {
6418
6572
  return this.proxyWindow;
6419
6573
  }
6574
+ if (customProperties.includes(key)) {
6575
+ return Reflect.get(target, key);
6576
+ }
6420
6577
  return bindFunctionToRawTarget(Reflect.get(target, key), target);
6421
6578
  },
6422
6579
  set: (target, key, value) => {
@@ -6428,6 +6585,9 @@ class IframeSandbox {
6428
6585
  if (key === 'location') {
6429
6586
  return Reflect.set(rawWindow, key, value);
6430
6587
  }
6588
+ if (!Reflect.has(target, key)) {
6589
+ customProperties.push(key);
6590
+ }
6431
6591
  Reflect.set(target, key, value);
6432
6592
  if (this.escapeProperties.includes(key)) {
6433
6593
  !Reflect.has(rawWindow, key) && this.escapeKeys.add(key);
@@ -6478,7 +6638,7 @@ class IframeSandbox {
6478
6638
  updateBrowserURLWithLocation(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.location);
6479
6639
  }
6480
6640
  removeRouteInfoForKeepAliveApp() {
6481
- removeStateAndPathFromBrowser(this.microAppWindow.__MICRO_APP_NAME__);
6641
+ removePathFromBrowser(this.microAppWindow.__MICRO_APP_NAME__);
6482
6642
  }
6483
6643
  /**
6484
6644
  * Format all html elements when init
@@ -6605,12 +6765,6 @@ class CreateApp {
6605
6765
  this.source.html = html;
6606
6766
  if (!this.isPrefetch && !this.isUnmounted()) {
6607
6767
  getRootContainer(this.container).mount(this);
6608
- // Abandonment plan
6609
- // if (this.isHidden()) {
6610
- // getRootContainer(this.container!).unmount()
6611
- // } else if (!this.isUnmounted()) {
6612
- // getRootContainer(this.container!).mount(this)
6613
- // }
6614
6768
  }
6615
6769
  else if (this.isPrerender) {
6616
6770
  /**
@@ -6678,8 +6832,7 @@ class CreateApp {
6678
6832
  // mount before prerender exec mount (loading source), set isPrerender to false
6679
6833
  this.isPrerender = false;
6680
6834
  // reset app state to LOADING
6681
- this.setAppState(appStates.LOADING);
6682
- return;
6835
+ return this.setAppState(appStates.LOADING);
6683
6836
  }
6684
6837
  this.createSandbox();
6685
6838
  const nextAction = () => {
@@ -6726,7 +6879,6 @@ class CreateApp {
6726
6879
  this.fiber = fiber;
6727
6880
  // use in sandbox/effect
6728
6881
  this.useMemoryRouter = useMemoryRouter;
6729
- // this.hiddenRouter = hiddenRouter ?? this.hiddenRouter
6730
6882
  const dispatchBeforeMount = () => dispatchLifecyclesEvent(this.container, this.name, lifeCycles.BEFOREMOUNT);
6731
6883
  if (this.isPrerender) {
6732
6884
  ((_d = this.preRenderEvents) !== null && _d !== void 0 ? _d : (this.preRenderEvents = [])).push(dispatchBeforeMount);
@@ -6832,6 +6984,12 @@ class CreateApp {
6832
6984
  (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.recordAndReleaseEffect({ keepAlive: true });
6833
6985
  }
6834
6986
  }
6987
+ /**
6988
+ * TODO: 这里增加一个处理,如果渲染完成时已经卸载,则进行一些操作
6989
+ * 如果是默认模式:删除所有事件和定时器
6990
+ * 如果是umd模式:重新记录和清空事件
6991
+ * 补充:非必需,优先级低
6992
+ */
6835
6993
  }
6836
6994
  /**
6837
6995
  * unmount app
@@ -6913,6 +7071,7 @@ class CreateApp {
6913
7071
  keepRouteState: keepRouteState && !destroy,
6914
7072
  destroy,
6915
7073
  clearData: clearData || destroy,
7074
+ useMemoryRouter: this.useMemoryRouter,
6916
7075
  });
6917
7076
  // dispatch unmount event to base app
6918
7077
  dispatchLifecyclesEvent(this.container, this.name, lifeCycles.UNMOUNT);
@@ -6956,7 +7115,16 @@ class CreateApp {
6956
7115
  // called after lifeCyclesEvent
6957
7116
  (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.removeRouteInfoForKeepAliveApp();
6958
7117
  }
6959
- (_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.recordAndReleaseEffect({ keepAlive: true });
7118
+ /**
7119
+ * Hidden app before the resources are loaded, then unmount the app
7120
+ */
7121
+ if (this.loadSourceLevel !== 2) {
7122
+ getRootContainer(this.container).unmount();
7123
+ }
7124
+ else {
7125
+ this.container = cloneContainer(pureCreateElement('div'), this.container, false);
7126
+ (_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.recordAndReleaseEffect({ keepAlive: true });
7127
+ }
6960
7128
  callback === null || callback === void 0 ? void 0 : callback();
6961
7129
  }
6962
7130
  // show app when connectedCallback called with keep-alive
@@ -6971,6 +7139,12 @@ class CreateApp {
6971
7139
  dispatchLifecyclesEvent(container, this.name, lifeCycles.BEFORESHOW);
6972
7140
  this.setKeepAliveState(keepAliveStates.KEEP_ALIVE_SHOW);
6973
7141
  this.container = cloneContainer(container, this.container, false);
7142
+ /**
7143
+ * TODO:
7144
+ * 1. iframe沙箱在关闭虚拟路由系统时,重新展示时不更新浏览器地址,这样和with沙箱保持一致。
7145
+ * 但是iframe是可以做到重新展示时更新浏览器地址的,这里临时不支持,等待后续with沙箱也支持的时候再优化
7146
+ * 只需要去除 if (this.useMemoryRouter) 的判断即可
7147
+ */
6974
7148
  if (this.useMemoryRouter) {
6975
7149
  // called before lifeCyclesEvent
6976
7150
  (_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.setRouteInfoForKeepAliveApp();