@micro-zoe/micro-app 1.0.0-beta.6 → 1.0.0-beta.7
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 +78 -41
- package/lib/index.esm.js.map +1 -1
- package/lib/index.min.js +1 -1
- package/lib/index.min.js.map +1 -1
- package/lib/index.umd.js +1 -1
- package/lib/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/typings/global.d.ts +11 -8
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '1.0.0-beta.
|
|
1
|
+
const version = '1.0.0-beta.7';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -1394,6 +1394,7 @@ var appStates;
|
|
|
1394
1394
|
appStates["CREATED"] = "created";
|
|
1395
1395
|
appStates["LOADING"] = "loading";
|
|
1396
1396
|
appStates["LOAD_FAILED"] = "load_failed";
|
|
1397
|
+
appStates["BEFORE_MOUNT"] = "before_mount";
|
|
1397
1398
|
appStates["MOUNTING"] = "mounting";
|
|
1398
1399
|
appStates["MOUNTED"] = "mounted";
|
|
1399
1400
|
appStates["UNMOUNT"] = "unmount";
|
|
@@ -3509,7 +3510,7 @@ function isEffectiveApp(appName) {
|
|
|
3509
3510
|
const app = appInstanceMap.get(appName);
|
|
3510
3511
|
/**
|
|
3511
3512
|
* !!(app && !app.isPrefetch && !app.isHidden())
|
|
3512
|
-
*
|
|
3513
|
+
* NOTE: 隐藏的keep-alive应用暂时不作为无效应用,原因如下
|
|
3513
3514
|
* 1、隐藏后才执行去除浏览器上的微应用的路由信息的操作,导致微应用的路由信息无法去除
|
|
3514
3515
|
* 2、如果保持隐藏应用内部正常跳转,阻止同步路由信息到浏览器,这样理论上是好的,但是对于location跳转改如何处理?location跳转是基于修改浏览器地址后发送popstate事件实现的,所以应该是在隐藏后不支持通过location进行跳转
|
|
3515
3516
|
*/
|
|
@@ -3865,6 +3866,39 @@ function createRouterApi() {
|
|
|
3865
3866
|
// clear element scope after navigate
|
|
3866
3867
|
removeDomScope();
|
|
3867
3868
|
}
|
|
3869
|
+
/**
|
|
3870
|
+
* navigation handler
|
|
3871
|
+
* @param appName app.name
|
|
3872
|
+
* @param app app instance
|
|
3873
|
+
* @param to router target options
|
|
3874
|
+
* @param replace use router.replace?
|
|
3875
|
+
*/
|
|
3876
|
+
function handleNavigate(appName, app, to, replace) {
|
|
3877
|
+
const microLocation = app.sandBox.proxyWindow.location;
|
|
3878
|
+
const targetLocation = createURL(to.path, microLocation.href);
|
|
3879
|
+
// Only get path data, even if the origin is different from microApp
|
|
3880
|
+
const currentFullPath = microLocation.pathname + microLocation.search + microLocation.hash;
|
|
3881
|
+
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
3882
|
+
if (currentFullPath !== targetFullPath || getMicroPathFromURL(appName) !== targetFullPath) {
|
|
3883
|
+
const methodName = (replace && to.replace !== false) || to.replace === true ? 'replaceState' : 'pushState';
|
|
3884
|
+
navigateWithRawHistory(appName, methodName, targetLocation, to.state);
|
|
3885
|
+
/**
|
|
3886
|
+
* TODO:
|
|
3887
|
+
* 1. 关闭虚拟路由的跳转地址不同:baseRoute + 子应用地址,文档中要说明
|
|
3888
|
+
* 2. 关闭虚拟路由时跳转方式不同:1、基座跳转但不发送popstate事件 2、控制子应用更新location,内部发送popstate事件。
|
|
3889
|
+
* 核心思路:减小对基座的影响(子应用跳转不向基座发送popstate事件,其他操作一致),但这是必要的吗,只是多了一个触发popstate的操作
|
|
3890
|
+
* 路由优化方案有两种:
|
|
3891
|
+
* 1、减少对基座的影响,主要是解决vue循环刷新的问题
|
|
3892
|
+
* 2、全局发送popstate事件,解决主、子都是vue3的冲突问题
|
|
3893
|
+
* 两者选一个吧,如果选2,则下面这两行代码可以去掉
|
|
3894
|
+
* NOTE1: history和search模式采用2,这样可以解决vue3的问题,custom采用1,避免vue循环刷新的问题,这样在用户出现问题时各有解决方案。但反过来说,每种方案又分别导致另外的问题,不统一,导致复杂度增高
|
|
3895
|
+
* NOTE2: 关闭虚拟路由,同时发送popstate事件还是无法解决vue3的问题(毕竟history.state理论上还是会冲突),那么就没必要发送popstate事件了。
|
|
3896
|
+
*/
|
|
3897
|
+
if (isRouterModeCustom(appName)) {
|
|
3898
|
+
updateMicroLocationWithEvent(appName, targetFullPath);
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3868
3902
|
/**
|
|
3869
3903
|
* create method of router.push/replace
|
|
3870
3904
|
* NOTE:
|
|
@@ -3883,33 +3917,16 @@ function createRouterApi() {
|
|
|
3883
3917
|
* 1. prerender app or hidden keep-alive app clear and record popstate event, so we cannot control app jump through the API
|
|
3884
3918
|
* 2. disable memory-router
|
|
3885
3919
|
*/
|
|
3920
|
+
/**
|
|
3921
|
+
* TODO: 子应用开始渲染但是还没渲染完成
|
|
3922
|
+
* 1、调用跳转改如何处理
|
|
3923
|
+
* 2、iframe的沙箱还没初始化时执行跳转报错,如何处理。。。
|
|
3924
|
+
* 3、hidden app 是否支持跳转
|
|
3925
|
+
*/
|
|
3886
3926
|
if (getActiveApps({ excludeHiddenApp: true, excludePreRender: true }).includes(appName)) {
|
|
3887
3927
|
const app = appInstanceMap.get(appName);
|
|
3888
|
-
const
|
|
3889
|
-
|
|
3890
|
-
// Only get path data, even if the origin is different from microApp
|
|
3891
|
-
const currentFullPath = microLocation.pathname + microLocation.search + microLocation.hash;
|
|
3892
|
-
const targetFullPath = targetLocation.pathname + targetLocation.search + targetLocation.hash;
|
|
3893
|
-
if (currentFullPath !== targetFullPath || getMicroPathFromURL(appName) !== targetFullPath) {
|
|
3894
|
-
const methodName = (replace && to.replace !== false) || to.replace === true ? 'replaceState' : 'pushState';
|
|
3895
|
-
navigateWithRawHistory(appName, methodName, targetLocation, to.state);
|
|
3896
|
-
/**
|
|
3897
|
-
* TODO:
|
|
3898
|
-
* 1. 关闭虚拟路由的跳转地址不同:baseRoute + 子应用地址,文档中要说明
|
|
3899
|
-
* 2. 关闭虚拟路由时跳转方式不同:1、基座跳转但不发送popstate事件 2、控制子应用更新location,内部发送popstate事件。
|
|
3900
|
-
* 补充:
|
|
3901
|
-
* 核心思路:减小对基座的影响(就是子应用跳转不向基座发送popstate事件,其他操作一致),但这是必要的吗,只是多了一个触发popstate的操作
|
|
3902
|
-
* 未来的思路有两种:
|
|
3903
|
-
* 1、减少对基座的影响,主要是解决vue循环刷新的问题
|
|
3904
|
-
* 2、全局发送popstate事件,解决主、子都是vue3的冲突问题
|
|
3905
|
-
* 两者选一个吧,如果选2,则下面这两行代码可以去掉
|
|
3906
|
-
* 要不这样吧,history和search模式采用2,这样可以解决vue3的问题,custom采用1,避免vue循环刷新的问题,这样在用户出现问题时各有解决方案。但反过来说,每种方案又分别导致另外的问题,不统一,导致复杂度增高
|
|
3907
|
-
* 如果关闭虚拟路由,同时发送popstate事件还是无法解决vue3的问题(毕竟history.state理论上还是会冲突),那么就没必要发送popstate事件了。
|
|
3908
|
-
*/
|
|
3909
|
-
if (isRouterModeCustom(appName)) {
|
|
3910
|
-
updateMicroLocationWithEvent(appName, targetFullPath);
|
|
3911
|
-
}
|
|
3912
|
-
}
|
|
3928
|
+
const navigateAction = () => handleNavigate(appName, app, to, replace);
|
|
3929
|
+
app.iframe ? app.sandBox.sandboxReady.then(navigateAction) : navigateAction();
|
|
3913
3930
|
}
|
|
3914
3931
|
else {
|
|
3915
3932
|
logWarn('navigation failed, app does not exist or is inactive');
|
|
@@ -4639,6 +4656,8 @@ class WithSandBox {
|
|
|
4639
4656
|
this.adapter = new Adapter();
|
|
4640
4657
|
// get scopeProperties and escapeProperties from plugins
|
|
4641
4658
|
this.getSpecialProperties(appName);
|
|
4659
|
+
// create location, history for child app
|
|
4660
|
+
this.patchRouter(appName, url, this.microAppWindow);
|
|
4642
4661
|
// patch window of child app
|
|
4643
4662
|
this.windowEffect = patchWindow(appName, this.microAppWindow, this);
|
|
4644
4663
|
// patch document of child app
|
|
@@ -4658,10 +4677,6 @@ class WithSandBox {
|
|
|
4658
4677
|
return;
|
|
4659
4678
|
this.active = true;
|
|
4660
4679
|
/* --- memory router part --- start */
|
|
4661
|
-
// create location, history for child app
|
|
4662
|
-
if (isUndefined(this.microAppWindow.location)) {
|
|
4663
|
-
this.setMicroAppRouter(this.microAppWindow.__MICRO_APP_NAME__, this.microAppWindow.__MICRO_APP_URL__, this.microAppWindow);
|
|
4664
|
-
}
|
|
4665
4680
|
// update microLocation, attach route info to browser url
|
|
4666
4681
|
this.initRouteState(defaultPage);
|
|
4667
4682
|
// unique listener of popstate event for sub app
|
|
@@ -4983,7 +4998,7 @@ class WithSandBox {
|
|
|
4983
4998
|
});
|
|
4984
4999
|
}
|
|
4985
5000
|
// set location & history for memory router
|
|
4986
|
-
|
|
5001
|
+
patchRouter(appName, url, microAppWindow) {
|
|
4987
5002
|
const { microLocation, microHistory } = createMicroRouter(appName, url);
|
|
4988
5003
|
rawDefineProperties(microAppWindow, {
|
|
4989
5004
|
location: {
|
|
@@ -5036,7 +5051,7 @@ class WithSandBox {
|
|
|
5036
5051
|
}
|
|
5037
5052
|
WithSandBox.activeCount = 0; // number of active sandbox
|
|
5038
5053
|
|
|
5039
|
-
function
|
|
5054
|
+
function patchRouter(appName, url, microAppWindow, browserHost) {
|
|
5040
5055
|
const childStaticLocation = new URL(url);
|
|
5041
5056
|
const childHost = childStaticLocation.protocol + '//' + childStaticLocation.host;
|
|
5042
5057
|
const childFullPath = childStaticLocation.pathname + childStaticLocation.search + childStaticLocation.hash;
|
|
@@ -5275,6 +5290,15 @@ function patchDocumentPrototype(appName, microAppWindow) {
|
|
|
5275
5290
|
const rawMicroGetElementsByClassName = microRootDocument.prototype.getElementsByClassName;
|
|
5276
5291
|
const rawMicroGetElementsByTagName = microRootDocument.prototype.getElementsByTagName;
|
|
5277
5292
|
const rawMicroGetElementsByName = microRootDocument.prototype.getElementsByName;
|
|
5293
|
+
const rawMicroElementFromPoint = microRootDocument.prototype.elementFromPoint;
|
|
5294
|
+
const rawMicroCaretRangeFromPoint = microRootDocument.prototype.caretRangeFromPoint;
|
|
5295
|
+
microRootDocument.prototype.caretRangeFromPoint = function caretRangeFromPoint(x, y) {
|
|
5296
|
+
// 这里this指向document才可以获取到子应用的document实例,range才可以被成功生成
|
|
5297
|
+
const element = rawMicroElementFromPoint.call(rawDocument, x, y);
|
|
5298
|
+
const range = rawMicroCaretRangeFromPoint.call(rawDocument, x, y);
|
|
5299
|
+
updateElementInfo(element, appName);
|
|
5300
|
+
return range;
|
|
5301
|
+
};
|
|
5278
5302
|
microRootDocument.prototype.createElement = function createElement(tagName, options) {
|
|
5279
5303
|
const element = rawMicroCreateElement.call(this, tagName, options);
|
|
5280
5304
|
return updateElementInfo(element, appName);
|
|
@@ -5790,13 +5814,12 @@ class IframeSandbox {
|
|
|
5790
5814
|
this.deleteIframeElement = this.createIframeElement(appName, browserHost);
|
|
5791
5815
|
this.microAppWindow = this.iframe.contentWindow;
|
|
5792
5816
|
this.patchIframe(this.microAppWindow, (resolve) => {
|
|
5793
|
-
// TODO: 优化代码
|
|
5794
5817
|
// create new html to iframe
|
|
5795
5818
|
this.createIframeTemplate(this.microAppWindow);
|
|
5796
5819
|
// get escapeProperties from plugins
|
|
5797
5820
|
this.getSpecialProperties(appName);
|
|
5798
5821
|
// patch location & history of child app
|
|
5799
|
-
this.proxyLocation =
|
|
5822
|
+
this.proxyLocation = patchRouter(appName, url, this.microAppWindow, browserHost);
|
|
5800
5823
|
// patch window of child app
|
|
5801
5824
|
this.windowEffect = patchWindow$1(appName, this.microAppWindow, this);
|
|
5802
5825
|
// patch document of child app
|
|
@@ -5807,7 +5830,7 @@ class IframeSandbox {
|
|
|
5807
5830
|
* create static properties
|
|
5808
5831
|
* NOTE:
|
|
5809
5832
|
* 1. execute as early as possible
|
|
5810
|
-
* 2. run after
|
|
5833
|
+
* 2. run after patchRouter & createProxyWindow
|
|
5811
5834
|
*/
|
|
5812
5835
|
this.initStaticGlobalKeys(appName, url);
|
|
5813
5836
|
resolve();
|
|
@@ -5914,7 +5937,7 @@ class IframeSandbox {
|
|
|
5914
5937
|
* create static properties
|
|
5915
5938
|
* NOTE:
|
|
5916
5939
|
* 1. execute as early as possible
|
|
5917
|
-
* 2. run after
|
|
5940
|
+
* 2. run after patchRouter & createProxyWindow
|
|
5918
5941
|
*/
|
|
5919
5942
|
initStaticGlobalKeys(appName, url) {
|
|
5920
5943
|
this.microAppWindow.__MICRO_APP_ENVIRONMENT__ = true;
|
|
@@ -6123,7 +6146,7 @@ IframeSandbox.activeCount = 0; // number of active sandbox
|
|
|
6123
6146
|
// micro app instances
|
|
6124
6147
|
const appInstanceMap = new Map();
|
|
6125
6148
|
class CreateApp {
|
|
6126
|
-
constructor({ name, url, container, scopecss, useSandbox, inline, iframe, ssrUrl, isPrefetch, prefetchLevel, }) {
|
|
6149
|
+
constructor({ name, url, container, scopecss, useSandbox, inline, iframe, ssrUrl, isPrefetch, prefetchLevel, routerMode, }) {
|
|
6127
6150
|
this.state = appStates.CREATED;
|
|
6128
6151
|
this.keepAliveState = null;
|
|
6129
6152
|
this.loadSourceLevel = 0;
|
|
@@ -6133,7 +6156,6 @@ class CreateApp {
|
|
|
6133
6156
|
// TODO: 类型优化,加上iframe沙箱
|
|
6134
6157
|
this.sandBox = null;
|
|
6135
6158
|
this.fiber = false;
|
|
6136
|
-
this.routerMode = DEFAULT_ROUTER_MODE;
|
|
6137
6159
|
appInstanceMap.set(name, this);
|
|
6138
6160
|
// init actions
|
|
6139
6161
|
this.name = name;
|
|
@@ -6142,6 +6164,11 @@ class CreateApp {
|
|
|
6142
6164
|
this.scopecss = this.useSandbox && scopecss;
|
|
6143
6165
|
this.inline = inline !== null && inline !== void 0 ? inline : false;
|
|
6144
6166
|
this.iframe = iframe !== null && iframe !== void 0 ? iframe : false;
|
|
6167
|
+
/**
|
|
6168
|
+
* NOTE:
|
|
6169
|
+
* 1. Navigate after micro-app created, before mount
|
|
6170
|
+
*/
|
|
6171
|
+
this.routerMode = routerMode || DEFAULT_ROUTER_MODE;
|
|
6145
6172
|
// not exist when prefetch 👇
|
|
6146
6173
|
this.container = container !== null && container !== void 0 ? container : null;
|
|
6147
6174
|
this.ssrUrl = ssrUrl !== null && ssrUrl !== void 0 ? ssrUrl : '';
|
|
@@ -6237,6 +6264,7 @@ class CreateApp {
|
|
|
6237
6264
|
return this.setAppState(appStates.LOADING);
|
|
6238
6265
|
}
|
|
6239
6266
|
this.createSandbox();
|
|
6267
|
+
this.setAppState(appStates.BEFORE_MOUNT);
|
|
6240
6268
|
const nextAction = () => {
|
|
6241
6269
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
6242
6270
|
/**
|
|
@@ -6350,7 +6378,10 @@ class CreateApp {
|
|
|
6350
6378
|
if (isPromise(umdHookMountResult)) {
|
|
6351
6379
|
umdHookMountResult
|
|
6352
6380
|
.then(() => this.dispatchMountedEvent())
|
|
6353
|
-
.catch(() =>
|
|
6381
|
+
.catch((e) => {
|
|
6382
|
+
logError('An error occurred in window.mount \n', this.name, e);
|
|
6383
|
+
this.dispatchMountedEvent();
|
|
6384
|
+
});
|
|
6354
6385
|
}
|
|
6355
6386
|
else {
|
|
6356
6387
|
this.dispatchMountedEvent();
|
|
@@ -7615,6 +7646,7 @@ function defineElement(tagName) {
|
|
|
7615
7646
|
inline: this.getDisposeResult('inline'),
|
|
7616
7647
|
iframe: this.getDisposeResult('iframe'),
|
|
7617
7648
|
ssrUrl: this.ssrUrl,
|
|
7649
|
+
routerMode: this.getMemoryRouterMode(),
|
|
7618
7650
|
});
|
|
7619
7651
|
};
|
|
7620
7652
|
/**
|
|
@@ -7647,7 +7679,12 @@ function defineElement(tagName) {
|
|
|
7647
7679
|
*/
|
|
7648
7680
|
handleMount(app) {
|
|
7649
7681
|
app.isPrefetch = false;
|
|
7650
|
-
|
|
7682
|
+
/**
|
|
7683
|
+
* Fix error when navigate before app.mount by microApp.router.push(...)
|
|
7684
|
+
* Issue: https://github.com/micro-zoe/micro-app/issues/908
|
|
7685
|
+
*/
|
|
7686
|
+
app.setAppState(appStates.BEFORE_MOUNT);
|
|
7687
|
+
// exec mount async, simulate the first render scene
|
|
7651
7688
|
defer(() => this.mount(app));
|
|
7652
7689
|
}
|
|
7653
7690
|
/**
|