@micro-zoe/micro-app 1.0.0-alpha.3 → 1.0.0-alpha.4
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.d.ts +1 -0
- package/lib/index.esm.js +238 -80
- 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 +3 -1
- package/typings/global.d.ts +31 -5
package/lib/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ declare module '@micro-zoe/micro-app/micro_app' {
|
|
|
41
41
|
'disable-scopecss'?: boolean;
|
|
42
42
|
'disable-sandbox'?: boolean;
|
|
43
43
|
'disable-memory-router'?: boolean;
|
|
44
|
+
'disable-patch-request'?: boolean;
|
|
44
45
|
'keep-router-state'?: boolean;
|
|
45
46
|
'hidden-router'?: boolean;
|
|
46
47
|
esmodule?: boolean;
|
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = '1.0.0-alpha.
|
|
1
|
+
const version = '1.0.0-alpha.4';
|
|
2
2
|
// do not use isUndefined
|
|
3
3
|
const isBrowser = typeof window !== 'undefined';
|
|
4
4
|
// do not use isUndefined
|
|
@@ -502,6 +502,66 @@ function fetchSource(url, appName = null, options = {}) {
|
|
|
502
502
|
});
|
|
503
503
|
}
|
|
504
504
|
|
|
505
|
+
class HTMLLoader {
|
|
506
|
+
static getInstance() {
|
|
507
|
+
if (!this.instance) {
|
|
508
|
+
this.instance = new HTMLLoader();
|
|
509
|
+
}
|
|
510
|
+
return this.instance;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* run logic of load and format html
|
|
514
|
+
* @param successCb success callback
|
|
515
|
+
* @param errorCb error callback, type: (err: Error, meetFetchErr: boolean) => void
|
|
516
|
+
*/
|
|
517
|
+
run(app, successCb) {
|
|
518
|
+
const appName = app.name;
|
|
519
|
+
const htmlUrl = app.ssrUrl || app.url;
|
|
520
|
+
fetchSource(htmlUrl, appName, { cache: 'no-cache' }).then((htmlStr) => {
|
|
521
|
+
if (!htmlStr) {
|
|
522
|
+
const msg = 'html is empty, please check in detail';
|
|
523
|
+
app.onerror(new Error(msg));
|
|
524
|
+
return logError(msg, appName);
|
|
525
|
+
}
|
|
526
|
+
htmlStr = this.formatHTML(htmlUrl, htmlStr, appName);
|
|
527
|
+
successCb(htmlStr, app);
|
|
528
|
+
}).catch((e) => {
|
|
529
|
+
logError(`Failed to fetch data from ${app.url}, micro-app stop rendering`, appName, e);
|
|
530
|
+
app.onLoadError(e);
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
formatHTML(htmlUrl, htmlStr, appName) {
|
|
534
|
+
return this.processHtml(htmlUrl, htmlStr, appName, microApp.plugins)
|
|
535
|
+
.replace(/<head[^>]*>[\s\S]*?<\/head>/i, (match) => {
|
|
536
|
+
return match
|
|
537
|
+
.replace(/<head/i, '<micro-app-head')
|
|
538
|
+
.replace(/<\/head>/i, '</micro-app-head>');
|
|
539
|
+
})
|
|
540
|
+
.replace(/<body[^>]*>[\s\S]*?<\/body>/i, (match) => {
|
|
541
|
+
return match
|
|
542
|
+
.replace(/<body/i, '<micro-app-body')
|
|
543
|
+
.replace(/<\/body>/i, '</micro-app-body>');
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
processHtml(url, code, appName, plugins) {
|
|
547
|
+
var _a;
|
|
548
|
+
if (!plugins)
|
|
549
|
+
return code;
|
|
550
|
+
const mergedPlugins = [];
|
|
551
|
+
plugins.global && mergedPlugins.push(...plugins.global);
|
|
552
|
+
((_a = plugins.modules) === null || _a === void 0 ? void 0 : _a[appName]) && mergedPlugins.push(...plugins.modules[appName]);
|
|
553
|
+
if (mergedPlugins.length > 0) {
|
|
554
|
+
return mergedPlugins.reduce((preCode, plugin) => {
|
|
555
|
+
if (isPlainObject(plugin) && isFunction(plugin.processHtml)) {
|
|
556
|
+
return plugin.processHtml(preCode, url, plugin.options);
|
|
557
|
+
}
|
|
558
|
+
return preCode;
|
|
559
|
+
}, code);
|
|
560
|
+
}
|
|
561
|
+
return code;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
505
565
|
// common reg
|
|
506
566
|
const rootSelectorREG = /(^|\s+)(html|:root)(?=[\s>~[.#:]+|$)/;
|
|
507
567
|
const bodySelectorREG = /(^|\s+)((html[\s>~]+body)|body)(?=[\s>~[.#:]+|$)/;
|
|
@@ -1143,12 +1203,12 @@ function handleNewNode(parent, child, app) {
|
|
|
1143
1203
|
return child;
|
|
1144
1204
|
}
|
|
1145
1205
|
else if (child instanceof HTMLLinkElement) {
|
|
1146
|
-
if (child.hasAttribute('exclude')) {
|
|
1206
|
+
if (child.hasAttribute('exclude') || checkExcludeUrl(child.getAttribute('href'), app.name)) {
|
|
1147
1207
|
const linkReplaceComment = document.createComment('link element with exclude attribute ignored by micro-app');
|
|
1148
1208
|
dynamicElementInMicroAppMap.set(child, linkReplaceComment);
|
|
1149
1209
|
return linkReplaceComment;
|
|
1150
1210
|
}
|
|
1151
|
-
else if (child.hasAttribute('ignore')) {
|
|
1211
|
+
else if (child.hasAttribute('ignore') || checkIgnoreUrl(child.getAttribute('href'), app.name)) {
|
|
1152
1212
|
return child;
|
|
1153
1213
|
}
|
|
1154
1214
|
const { url, info, replaceComment } = extractLinkFromHtml(child, parent, app, true);
|
|
@@ -1657,11 +1717,14 @@ const globalScripts = new Map();
|
|
|
1657
1717
|
function extractScriptElement(script, parent, app, isDynamic = false) {
|
|
1658
1718
|
let replaceComment = null;
|
|
1659
1719
|
let src = script.getAttribute('src');
|
|
1660
|
-
if (
|
|
1720
|
+
if (src) {
|
|
1721
|
+
src = CompletionPath(src, app.url);
|
|
1722
|
+
}
|
|
1723
|
+
if (script.hasAttribute('exclude') || checkExcludeUrl(src, app.name)) {
|
|
1661
1724
|
replaceComment = document.createComment('script element with exclude attribute removed by micro-app');
|
|
1662
1725
|
}
|
|
1663
|
-
else if ((script.type && !['text/javascript', 'text/ecmascript', 'application/javascript', 'application/ecmascript', 'module'].includes(script.type)) ||
|
|
1664
|
-
script.hasAttribute('ignore')) {
|
|
1726
|
+
else if ((script.type && !['text/javascript', 'text/ecmascript', 'application/javascript', 'application/ecmascript', 'module', 'systemjs-module', 'systemjs-importmap'].includes(script.type)) ||
|
|
1727
|
+
script.hasAttribute('ignore') || checkIgnoreUrl(src, app.name)) {
|
|
1665
1728
|
return null;
|
|
1666
1729
|
}
|
|
1667
1730
|
else if ((globalEnv.supportModuleScript && script.noModule) ||
|
|
@@ -1669,7 +1732,6 @@ function extractScriptElement(script, parent, app, isDynamic = false) {
|
|
|
1669
1732
|
replaceComment = document.createComment(`${script.noModule ? 'noModule' : 'module'} script ignored by micro-app`);
|
|
1670
1733
|
}
|
|
1671
1734
|
else if (src) { // remote script
|
|
1672
|
-
src = CompletionPath(src, app.url);
|
|
1673
1735
|
const info = {
|
|
1674
1736
|
code: '',
|
|
1675
1737
|
isExternal: true,
|
|
@@ -1719,6 +1781,46 @@ function extractScriptElement(script, parent, app, isDynamic = false) {
|
|
|
1719
1781
|
return parent.replaceChild(replaceComment, script);
|
|
1720
1782
|
}
|
|
1721
1783
|
}
|
|
1784
|
+
/**
|
|
1785
|
+
* get assets plugins
|
|
1786
|
+
* @param appName app name
|
|
1787
|
+
*/
|
|
1788
|
+
function getAssetsPlugins(appName) {
|
|
1789
|
+
var _a, _b, _c;
|
|
1790
|
+
const globalPlugins = ((_a = microApp.plugins) === null || _a === void 0 ? void 0 : _a.global) || [];
|
|
1791
|
+
const modulePlugins = ((_c = (_b = microApp.plugins) === null || _b === void 0 ? void 0 : _b.modules) === null || _c === void 0 ? void 0 : _c[appName]) || [];
|
|
1792
|
+
return [...globalPlugins, ...modulePlugins];
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* whether the url needs to be excluded
|
|
1796
|
+
* @param url css or js link
|
|
1797
|
+
* @param plugins microApp plugins
|
|
1798
|
+
*/
|
|
1799
|
+
function checkExcludeUrl(url, appName) {
|
|
1800
|
+
if (!url)
|
|
1801
|
+
return false;
|
|
1802
|
+
const plugins = getAssetsPlugins(appName) || [];
|
|
1803
|
+
return plugins.some(plugin => {
|
|
1804
|
+
if (!plugin.excludeChecker)
|
|
1805
|
+
return false;
|
|
1806
|
+
return plugin.excludeChecker(url);
|
|
1807
|
+
});
|
|
1808
|
+
}
|
|
1809
|
+
/**
|
|
1810
|
+
* whether the url needs to be ignore
|
|
1811
|
+
* @param url css or js link
|
|
1812
|
+
* @param plugins microApp plugins
|
|
1813
|
+
*/
|
|
1814
|
+
function checkIgnoreUrl(url, appName) {
|
|
1815
|
+
if (!url)
|
|
1816
|
+
return false;
|
|
1817
|
+
const plugins = getAssetsPlugins(appName) || [];
|
|
1818
|
+
return plugins.some(plugin => {
|
|
1819
|
+
if (!plugin.ignoreChecker)
|
|
1820
|
+
return false;
|
|
1821
|
+
return plugin.ignoreChecker(url);
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1722
1824
|
/**
|
|
1723
1825
|
* Get remote resources of script
|
|
1724
1826
|
* @param wrapElement htmlDom
|
|
@@ -1898,7 +2000,7 @@ function runDynamicRemoteScript(url, info, app, originScript) {
|
|
|
1898
2000
|
catch (e) {
|
|
1899
2001
|
console.error(`[micro-app from runDynamicScript] app ${app.name}: `, e, url);
|
|
1900
2002
|
}
|
|
1901
|
-
!info.module &&
|
|
2003
|
+
!info.module && dispatchScriptOnLoadEvent();
|
|
1902
2004
|
}).catch((err) => {
|
|
1903
2005
|
logError(err, app.name);
|
|
1904
2006
|
dispatchOnErrorEvent(originScript);
|
|
@@ -1946,6 +2048,7 @@ function runCode2Function(code, info) {
|
|
|
1946
2048
|
* @param info source script info
|
|
1947
2049
|
*/
|
|
1948
2050
|
function bindScope(url, app, code, info) {
|
|
2051
|
+
// TODO: 增加缓存机制
|
|
1949
2052
|
if (isPlainObject(microApp.plugins)) {
|
|
1950
2053
|
code = usePlugins(url, code, app.name, microApp.plugins, info);
|
|
1951
2054
|
}
|
|
@@ -2002,10 +2105,10 @@ function flatChildren(parent, app, microAppHead) {
|
|
|
2002
2105
|
});
|
|
2003
2106
|
for (const dom of children) {
|
|
2004
2107
|
if (dom instanceof HTMLLinkElement) {
|
|
2005
|
-
if (dom.hasAttribute('exclude')) {
|
|
2108
|
+
if (dom.hasAttribute('exclude') || checkExcludeUrl(dom.getAttribute('href'), app.name)) {
|
|
2006
2109
|
parent.replaceChild(document.createComment('link element with exclude attribute ignored by micro-app'), dom);
|
|
2007
2110
|
}
|
|
2008
|
-
else if (!dom.hasAttribute('ignore')) {
|
|
2111
|
+
else if (!(dom.hasAttribute('ignore') || checkIgnoreUrl(dom.getAttribute('href'), app.name))) {
|
|
2009
2112
|
extractLinkFromHtml(dom, parent, app);
|
|
2010
2113
|
}
|
|
2011
2114
|
else if (dom.hasAttribute('href')) {
|
|
@@ -2059,34 +2162,6 @@ function extractSourceDom(htmlStr, app) {
|
|
|
2059
2162
|
app.onLoad(wrapElement);
|
|
2060
2163
|
}
|
|
2061
2164
|
}
|
|
2062
|
-
/**
|
|
2063
|
-
* Get and format html
|
|
2064
|
-
* @param app app
|
|
2065
|
-
*/
|
|
2066
|
-
function extractHtml(app) {
|
|
2067
|
-
fetchSource(app.ssrUrl || app.url, app.name, { cache: 'no-cache' }).then((htmlStr) => {
|
|
2068
|
-
if (!htmlStr) {
|
|
2069
|
-
const msg = 'html is empty, please check in detail';
|
|
2070
|
-
app.onerror(new Error(msg));
|
|
2071
|
-
return logError(msg, app.name);
|
|
2072
|
-
}
|
|
2073
|
-
htmlStr = htmlStr
|
|
2074
|
-
.replace(/<head[^>]*>[\s\S]*?<\/head>/i, (match) => {
|
|
2075
|
-
return match
|
|
2076
|
-
.replace(/<head/i, '<micro-app-head')
|
|
2077
|
-
.replace(/<\/head>/i, '</micro-app-head>');
|
|
2078
|
-
})
|
|
2079
|
-
.replace(/<body[^>]*>[\s\S]*?<\/body>/i, (match) => {
|
|
2080
|
-
return match
|
|
2081
|
-
.replace(/<body/i, '<micro-app-body')
|
|
2082
|
-
.replace(/<\/body>/i, '</micro-app-body>');
|
|
2083
|
-
});
|
|
2084
|
-
extractSourceDom(htmlStr, app);
|
|
2085
|
-
}).catch((e) => {
|
|
2086
|
-
logError(`Failed to fetch data from ${app.url}, micro-app stop rendering`, app.name, e);
|
|
2087
|
-
app.onLoadError(e);
|
|
2088
|
-
});
|
|
2089
|
-
}
|
|
2090
2165
|
|
|
2091
2166
|
class EventCenter {
|
|
2092
2167
|
constructor() {
|
|
@@ -2369,12 +2444,39 @@ function rebuildDataCenterSnapshot(microAppEventCenter) {
|
|
|
2369
2444
|
}
|
|
2370
2445
|
}
|
|
2371
2446
|
|
|
2447
|
+
// 管理 app 的单例
|
|
2448
|
+
class AppManager {
|
|
2449
|
+
constructor() {
|
|
2450
|
+
// Todo: appInstanceMap 由 AppManager 来创建,不再由 create_app 管理
|
|
2451
|
+
this.appInstanceMap = appInstanceMap;
|
|
2452
|
+
}
|
|
2453
|
+
static getInstance() {
|
|
2454
|
+
if (!this.instance) {
|
|
2455
|
+
this.instance = new AppManager();
|
|
2456
|
+
}
|
|
2457
|
+
return this.instance;
|
|
2458
|
+
}
|
|
2459
|
+
get(appName) {
|
|
2460
|
+
return this.appInstanceMap.get(appName);
|
|
2461
|
+
}
|
|
2462
|
+
set(appName, app) {
|
|
2463
|
+
this.appInstanceMap.set(appName, app);
|
|
2464
|
+
}
|
|
2465
|
+
getAll() {
|
|
2466
|
+
return Array.from(this.appInstanceMap.values());
|
|
2467
|
+
}
|
|
2468
|
+
clear() {
|
|
2469
|
+
this.appInstanceMap.clear();
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2372
2473
|
function unmountNestedApp() {
|
|
2373
|
-
|
|
2474
|
+
releaseUnmountOfNestedApp();
|
|
2475
|
+
AppManager.getInstance().getAll().forEach(app => {
|
|
2374
2476
|
// @ts-ignore
|
|
2375
2477
|
app.container && getRootContainer(app.container).disconnectedCallback();
|
|
2376
2478
|
});
|
|
2377
|
-
!window.__MICRO_APP_UMD_MODE__ &&
|
|
2479
|
+
!window.__MICRO_APP_UMD_MODE__ && AppManager.getInstance().clear();
|
|
2378
2480
|
}
|
|
2379
2481
|
// release listener
|
|
2380
2482
|
function releaseUnmountOfNestedApp() {
|
|
@@ -2586,6 +2688,13 @@ function effect(appName, microAppWindow) {
|
|
|
2586
2688
|
let umdIntervalIdMap = new Map();
|
|
2587
2689
|
let umdTimeoutIdMap = new Map();
|
|
2588
2690
|
let umdOnClickHandler;
|
|
2691
|
+
const clearUmdSnapshotData = () => {
|
|
2692
|
+
umdWindowListenerMap.clear();
|
|
2693
|
+
umdIntervalIdMap.clear();
|
|
2694
|
+
umdTimeoutIdMap.clear();
|
|
2695
|
+
umdDocumentListenerMap.clear();
|
|
2696
|
+
umdOnClickHandler = null;
|
|
2697
|
+
};
|
|
2589
2698
|
// record event and timer before exec umdMountHook
|
|
2590
2699
|
const recordUmdEffect = () => {
|
|
2591
2700
|
// record window event
|
|
@@ -2631,13 +2740,12 @@ function effect(appName, microAppWindow) {
|
|
|
2631
2740
|
// rebuild onclick event
|
|
2632
2741
|
umdOnClickHandler && documentClickListMap.set(appName, umdOnClickHandler);
|
|
2633
2742
|
// rebuild document event
|
|
2634
|
-
setCurrentAppName(appName);
|
|
2635
2743
|
umdDocumentListenerMap.forEach((listenerList, type) => {
|
|
2636
2744
|
for (const listener of listenerList) {
|
|
2637
2745
|
document.addEventListener(type, listener, listener === null || listener === void 0 ? void 0 : listener.__MICRO_APP_MARK_OPTIONS__);
|
|
2638
2746
|
}
|
|
2639
2747
|
});
|
|
2640
|
-
|
|
2748
|
+
clearUmdSnapshotData();
|
|
2641
2749
|
};
|
|
2642
2750
|
// release all event listener & interval & timeout when unmount app
|
|
2643
2751
|
const releaseEffect = () => {
|
|
@@ -2974,6 +3082,15 @@ function createMicroHistory(appName, microLocation) {
|
|
|
2974
3082
|
}
|
|
2975
3083
|
const rawValue = Reflect.get(target, key);
|
|
2976
3084
|
return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'HISTORY') : rawValue;
|
|
3085
|
+
},
|
|
3086
|
+
set(target, key, value) {
|
|
3087
|
+
Reflect.set(target, key, value);
|
|
3088
|
+
/**
|
|
3089
|
+
* If the set() method returns false, and the assignment happened in strict-mode code, a TypeError will be thrown.
|
|
3090
|
+
* e.g. history.state = {}
|
|
3091
|
+
* TypeError: 'set' on proxy: trap returned falsish for property 'state'
|
|
3092
|
+
*/
|
|
3093
|
+
return true;
|
|
2977
3094
|
}
|
|
2978
3095
|
});
|
|
2979
3096
|
}
|
|
@@ -3145,7 +3262,7 @@ function createRouterApi() {
|
|
|
3145
3262
|
* NOTE:
|
|
3146
3263
|
* 1. Modify browser url first, and then run guards,
|
|
3147
3264
|
* consistent with the browser forward & back button
|
|
3148
|
-
* 2.
|
|
3265
|
+
* 2. Prevent the element binding
|
|
3149
3266
|
* @param appName app name
|
|
3150
3267
|
* @param to target location
|
|
3151
3268
|
* @param from old location
|
|
@@ -3212,12 +3329,14 @@ function createRouterApi() {
|
|
|
3212
3329
|
const defaultPageRecord = useMapRecord();
|
|
3213
3330
|
/**
|
|
3214
3331
|
* defaultPage only effect when mount, and has lower priority than query on browser url
|
|
3215
|
-
*
|
|
3216
|
-
*
|
|
3332
|
+
* SetDefaultPageOptions {
|
|
3333
|
+
* @param name app name
|
|
3334
|
+
* @param path page path
|
|
3335
|
+
* }
|
|
3217
3336
|
*/
|
|
3218
|
-
function setDefaultPage(
|
|
3219
|
-
appName = formatAppName(
|
|
3220
|
-
if (!appName || !path) {
|
|
3337
|
+
function setDefaultPage(options) {
|
|
3338
|
+
const appName = formatAppName(options.name);
|
|
3339
|
+
if (!appName || !options.path) {
|
|
3221
3340
|
if (process.env.NODE_ENV !== 'production') {
|
|
3222
3341
|
if (!appName) {
|
|
3223
3342
|
logWarn(`setDefaultPage: invalid appName "${appName}"`);
|
|
@@ -3228,7 +3347,7 @@ function createRouterApi() {
|
|
|
3228
3347
|
}
|
|
3229
3348
|
return noopFalse;
|
|
3230
3349
|
}
|
|
3231
|
-
return defaultPageRecord.add(appName, path);
|
|
3350
|
+
return defaultPageRecord.add(appName, options.path);
|
|
3232
3351
|
}
|
|
3233
3352
|
function removeDefaultPage(appName) {
|
|
3234
3353
|
appName = formatAppName(appName);
|
|
@@ -3254,6 +3373,10 @@ function createRouterApi() {
|
|
|
3254
3373
|
removeDomScope();
|
|
3255
3374
|
const rawValue = Reflect.get(target, key);
|
|
3256
3375
|
return isFunction(rawValue) ? bindFunctionToRawObject(target, rawValue, 'BASEROUTER') : rawValue;
|
|
3376
|
+
},
|
|
3377
|
+
set(target, key, value) {
|
|
3378
|
+
Reflect.set(target, key, value);
|
|
3379
|
+
return true;
|
|
3257
3380
|
}
|
|
3258
3381
|
});
|
|
3259
3382
|
}
|
|
@@ -3655,6 +3778,8 @@ class SandBox {
|
|
|
3655
3778
|
this.injectedKeys = new Set();
|
|
3656
3779
|
// Properties escape to rawWindow, cleared when unmount
|
|
3657
3780
|
this.escapeKeys = new Set();
|
|
3781
|
+
// record injected values before the first execution of umdHookMount and rebuild before remount umd app
|
|
3782
|
+
// private recordUmdInjectedValues?: Map<PropertyKey, unknown>
|
|
3658
3783
|
// sandbox state
|
|
3659
3784
|
this.active = false;
|
|
3660
3785
|
this.microAppWindow = {}; // Proxy target
|
|
@@ -3668,7 +3793,8 @@ class SandBox {
|
|
|
3668
3793
|
// inject global properties
|
|
3669
3794
|
this.initStaticGlobalKeys(this.microAppWindow, appName, url, useMemoryRouter);
|
|
3670
3795
|
}
|
|
3671
|
-
|
|
3796
|
+
// TODO: 重构
|
|
3797
|
+
start(umdMode = false, baseRoute = '', useMemoryRouter = true, defaultPage = '', disablePatchRequest = false) {
|
|
3672
3798
|
if (!this.active) {
|
|
3673
3799
|
this.active = true;
|
|
3674
3800
|
if (useMemoryRouter) {
|
|
@@ -3679,8 +3805,13 @@ class SandBox {
|
|
|
3679
3805
|
else {
|
|
3680
3806
|
this.microAppWindow.__MICRO_APP_BASE_ROUTE__ = this.microAppWindow.__MICRO_APP_BASE_URL__ = baseRoute;
|
|
3681
3807
|
}
|
|
3682
|
-
|
|
3683
|
-
|
|
3808
|
+
/**
|
|
3809
|
+
* 1. prevent the key deleted during sandBox.stop after rewrite
|
|
3810
|
+
* 2. umd mode will not delete any keys during sandBox.stop
|
|
3811
|
+
*/
|
|
3812
|
+
if (!umdMode) {
|
|
3813
|
+
this.initGlobalKeysWhenStart(this.microAppWindow, this.proxyWindow.__MICRO_APP_NAME__, this.proxyWindow.__MICRO_APP_URL__, disablePatchRequest);
|
|
3814
|
+
}
|
|
3684
3815
|
if (++SandBox.activeCount === 1) {
|
|
3685
3816
|
effectDocumentEvent();
|
|
3686
3817
|
patchElementPrototypeMethods();
|
|
@@ -3690,7 +3821,7 @@ class SandBox {
|
|
|
3690
3821
|
fixBabelPolyfill6();
|
|
3691
3822
|
}
|
|
3692
3823
|
}
|
|
3693
|
-
stop(keepRouteState, clearEventSource) {
|
|
3824
|
+
stop(umdMode, keepRouteState, clearEventSource) {
|
|
3694
3825
|
if (this.active) {
|
|
3695
3826
|
this.releaseEffect();
|
|
3696
3827
|
this.microAppWindow.microApp.clearDataListener();
|
|
@@ -3707,15 +3838,18 @@ class SandBox {
|
|
|
3707
3838
|
* NOTE:
|
|
3708
3839
|
* 1. injectedKeys and escapeKeys must be placed at the back
|
|
3709
3840
|
* 2. if key in initial microAppWindow, and then rewrite, this key will be delete from microAppWindow when stop, and lost when restart
|
|
3841
|
+
* 3. umd mode will not delete global keys
|
|
3710
3842
|
*/
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3843
|
+
if (!umdMode) {
|
|
3844
|
+
this.injectedKeys.forEach((key) => {
|
|
3845
|
+
Reflect.deleteProperty(this.microAppWindow, key);
|
|
3846
|
+
});
|
|
3847
|
+
this.injectedKeys.clear();
|
|
3848
|
+
this.escapeKeys.forEach((key) => {
|
|
3849
|
+
Reflect.deleteProperty(globalEnv.rawWindow, key);
|
|
3850
|
+
});
|
|
3851
|
+
this.escapeKeys.clear();
|
|
3852
|
+
}
|
|
3719
3853
|
if (--SandBox.activeCount === 0) {
|
|
3720
3854
|
releaseEffectDocumentEvent();
|
|
3721
3855
|
releasePatches();
|
|
@@ -3726,19 +3860,19 @@ class SandBox {
|
|
|
3726
3860
|
}
|
|
3727
3861
|
// record umd snapshot before the first execution of umdHookMount
|
|
3728
3862
|
recordUmdSnapshot() {
|
|
3729
|
-
this.microAppWindow.__MICRO_APP_UMD_MODE__ = true
|
|
3863
|
+
// this.microAppWindow.__MICRO_APP_UMD_MODE__ = true
|
|
3730
3864
|
this.recordUmdEffect();
|
|
3731
3865
|
recordDataCenterSnapshot(this.microAppWindow.microApp);
|
|
3732
|
-
this.recordUmdInjectedValues = new Map()
|
|
3733
|
-
this.injectedKeys.forEach((key) => {
|
|
3734
|
-
|
|
3735
|
-
})
|
|
3866
|
+
// this.recordUmdInjectedValues = new Map<PropertyKey, unknown>()
|
|
3867
|
+
// this.injectedKeys.forEach((key: PropertyKey) => {
|
|
3868
|
+
// this.recordUmdInjectedValues!.set(key, Reflect.get(this.microAppWindow, key))
|
|
3869
|
+
// })
|
|
3736
3870
|
}
|
|
3737
3871
|
// rebuild umd snapshot before remount umd app
|
|
3738
3872
|
rebuildUmdSnapshot() {
|
|
3739
|
-
this.recordUmdInjectedValues
|
|
3740
|
-
|
|
3741
|
-
})
|
|
3873
|
+
// this.recordUmdInjectedValues!.forEach((value: unknown, key: PropertyKey) => {
|
|
3874
|
+
// Reflect.set(this.proxyWindow, key, value)
|
|
3875
|
+
// })
|
|
3742
3876
|
this.rebuildUmdEffect();
|
|
3743
3877
|
rebuildDataCenterSnapshot(this.microAppWindow.microApp);
|
|
3744
3878
|
}
|
|
@@ -3942,11 +4076,13 @@ class SandBox {
|
|
|
3942
4076
|
* @param microAppWindow micro window
|
|
3943
4077
|
* @param appName app name
|
|
3944
4078
|
* @param url app url
|
|
4079
|
+
* @param disablePatchRequest prevent rewrite request method of child app
|
|
3945
4080
|
*/
|
|
3946
|
-
initGlobalKeysWhenStart(microAppWindow, appName, url) {
|
|
4081
|
+
initGlobalKeysWhenStart(microAppWindow, appName, url, disablePatchRequest) {
|
|
3947
4082
|
microAppWindow.hasOwnProperty = (key) => rawHasOwnProperty.call(microAppWindow, key) || rawHasOwnProperty.call(globalEnv.rawWindow, key);
|
|
3948
4083
|
this.setHijackProperty(microAppWindow, appName);
|
|
3949
|
-
|
|
4084
|
+
if (!disablePatchRequest)
|
|
4085
|
+
this.patchRequestApi(microAppWindow, appName, url);
|
|
3950
4086
|
}
|
|
3951
4087
|
// set hijack Properties to microAppWindow
|
|
3952
4088
|
setHijackProperty(microAppWindow, appName) {
|
|
@@ -4071,6 +4207,14 @@ class SandBox {
|
|
|
4071
4207
|
const rawValue = Reflect.get(target, key);
|
|
4072
4208
|
return isFunction(rawValue) ? bindFunctionToRawObject(rawDocument, rawValue, 'DOCUMENT') : rawValue;
|
|
4073
4209
|
},
|
|
4210
|
+
set(target, key, value) {
|
|
4211
|
+
// Fix TypeError: Illegal invocation when set document.title
|
|
4212
|
+
Reflect.set(target, key, value);
|
|
4213
|
+
/**
|
|
4214
|
+
* If the set method returns false, and the assignment happened in strict-mode code, a TypeError will be thrown.
|
|
4215
|
+
*/
|
|
4216
|
+
return true;
|
|
4217
|
+
}
|
|
4074
4218
|
});
|
|
4075
4219
|
class MicroDocument {
|
|
4076
4220
|
static [Symbol.hasInstance](target) {
|
|
@@ -4094,11 +4238,16 @@ class SandBox {
|
|
|
4094
4238
|
* B.prototype.__proto__ === A.prototype // true
|
|
4095
4239
|
*/
|
|
4096
4240
|
Object.setPrototypeOf(MicroDocument, rawRootDocument);
|
|
4241
|
+
// Object.create(rawRootDocument.prototype) will cause MicroDocument and proxyDocument methods not same when exec Document.prototype.xxx = xxx in child app
|
|
4097
4242
|
Object.setPrototypeOf(MicroDocument.prototype, new Proxy(rawRootDocument.prototype, {
|
|
4098
4243
|
get(target, key) {
|
|
4099
4244
|
throttleDeferForSetAppName(appName);
|
|
4100
4245
|
const rawValue = Reflect.get(target, key);
|
|
4101
4246
|
return isFunction(rawValue) ? bindFunctionToRawObject(rawDocument, rawValue, 'DOCUMENT') : rawValue;
|
|
4247
|
+
},
|
|
4248
|
+
set(target, key, value) {
|
|
4249
|
+
Reflect.set(target, key, value);
|
|
4250
|
+
return true;
|
|
4102
4251
|
}
|
|
4103
4252
|
}));
|
|
4104
4253
|
return {
|
|
@@ -4173,7 +4322,7 @@ function dispatchCustomEventToMicroApp(eventName, appName, detail = {}) {
|
|
|
4173
4322
|
// micro app instances
|
|
4174
4323
|
const appInstanceMap = new Map();
|
|
4175
4324
|
class CreateApp {
|
|
4176
|
-
constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, useMemoryRouter, baseroute, keepRouteState, hiddenRouter, defaultPage, }) {
|
|
4325
|
+
constructor({ name, url, ssrUrl, container, inline, scopecss, useSandbox, useMemoryRouter, baseroute, keepRouteState, hiddenRouter, defaultPage, disablePatchRequest, }) {
|
|
4177
4326
|
this.state = appStates.CREATED;
|
|
4178
4327
|
this.keepAliveState = null;
|
|
4179
4328
|
this.keepAliveContainer = null;
|
|
@@ -4199,6 +4348,7 @@ class CreateApp {
|
|
|
4199
4348
|
this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : false;
|
|
4200
4349
|
this.hiddenRouter = hiddenRouter !== null && hiddenRouter !== void 0 ? hiddenRouter : false;
|
|
4201
4350
|
this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : '';
|
|
4351
|
+
this.disablePatchRequest = disablePatchRequest !== null && disablePatchRequest !== void 0 ? disablePatchRequest : false;
|
|
4202
4352
|
this.source = {
|
|
4203
4353
|
links: new Map(),
|
|
4204
4354
|
scripts: new Map(),
|
|
@@ -4209,7 +4359,7 @@ class CreateApp {
|
|
|
4209
4359
|
// Load resources
|
|
4210
4360
|
loadSourceCode() {
|
|
4211
4361
|
this.state = appStates.LOADING;
|
|
4212
|
-
|
|
4362
|
+
HTMLLoader.getInstance().run(this, extractSourceDom);
|
|
4213
4363
|
}
|
|
4214
4364
|
/**
|
|
4215
4365
|
* When resource is loaded, mount app if it is not prefetch or unmount
|
|
@@ -4249,8 +4399,9 @@ class CreateApp {
|
|
|
4249
4399
|
* @param inline js runs in inline mode
|
|
4250
4400
|
* @param baseroute route prefix, default is ''
|
|
4251
4401
|
* @param keepRouteState keep route state when unmount, default is false
|
|
4402
|
+
* @param disablePatchRequest prevent rewrite request method of child app
|
|
4252
4403
|
*/
|
|
4253
|
-
mount(container, inline, baseroute, keepRouteState, defaultPage, hiddenRouter) {
|
|
4404
|
+
mount(container, inline, baseroute, keepRouteState, defaultPage, hiddenRouter, disablePatchRequest) {
|
|
4254
4405
|
var _a, _b, _c;
|
|
4255
4406
|
this.inline = inline !== null && inline !== void 0 ? inline : this.inline;
|
|
4256
4407
|
this.keepRouteState = keepRouteState !== null && keepRouteState !== void 0 ? keepRouteState : this.keepRouteState;
|
|
@@ -4258,6 +4409,7 @@ class CreateApp {
|
|
|
4258
4409
|
this.baseroute = baseroute !== null && baseroute !== void 0 ? baseroute : this.baseroute;
|
|
4259
4410
|
this.defaultPage = defaultPage !== null && defaultPage !== void 0 ? defaultPage : this.defaultPage;
|
|
4260
4411
|
this.hiddenRouter = hiddenRouter !== null && hiddenRouter !== void 0 ? hiddenRouter : this.hiddenRouter;
|
|
4412
|
+
this.disablePatchRequest = disablePatchRequest !== null && disablePatchRequest !== void 0 ? disablePatchRequest : this.disablePatchRequest;
|
|
4261
4413
|
if (this.loadSourceLevel !== 2) {
|
|
4262
4414
|
this.state = appStates.LOADING;
|
|
4263
4415
|
return;
|
|
@@ -4265,13 +4417,12 @@ class CreateApp {
|
|
|
4265
4417
|
dispatchLifecyclesEvent(this.container, this.name, lifeCycles.BEFOREMOUNT);
|
|
4266
4418
|
this.state = appStates.MOUNTING;
|
|
4267
4419
|
cloneContainer(this.source.html, this.container, !this.umdMode);
|
|
4268
|
-
(_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.start(this.baseroute, this.useMemoryRouter, this.defaultPage);
|
|
4420
|
+
(_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.start(this.umdMode, this.baseroute, this.useMemoryRouter, this.defaultPage, this.disablePatchRequest);
|
|
4269
4421
|
let umdHookMountResult; // result of mount function
|
|
4270
4422
|
if (!this.umdMode) {
|
|
4271
4423
|
let hasDispatchMountedEvent = false;
|
|
4272
4424
|
// if all js are executed, param isFinished will be true
|
|
4273
4425
|
execScripts(this.source.scripts, this, (isFinished) => {
|
|
4274
|
-
var _a;
|
|
4275
4426
|
if (!this.umdMode) {
|
|
4276
4427
|
const { mount, unmount } = this.getUmdLibraryHooks();
|
|
4277
4428
|
// if mount & unmount is function, the sub app is umd mode
|
|
@@ -4279,7 +4430,9 @@ class CreateApp {
|
|
|
4279
4430
|
this.umdHookMount = mount;
|
|
4280
4431
|
this.umdHookUnmount = unmount;
|
|
4281
4432
|
this.umdMode = true;
|
|
4282
|
-
(
|
|
4433
|
+
if (this.sandBox)
|
|
4434
|
+
this.sandBox.proxyWindow.__MICRO_APP_UMD_MODE__ = true;
|
|
4435
|
+
// this.sandBox?.recordUmdSnapshot()
|
|
4283
4436
|
try {
|
|
4284
4437
|
umdHookMountResult = this.umdHookMount();
|
|
4285
4438
|
}
|
|
@@ -4381,20 +4534,23 @@ class CreateApp {
|
|
|
4381
4534
|
* @param unmountcb callback of unmount
|
|
4382
4535
|
*/
|
|
4383
4536
|
actionsForUnmount(destroy, unmountcb) {
|
|
4384
|
-
var _a;
|
|
4537
|
+
var _a, _b;
|
|
4385
4538
|
if (destroy) {
|
|
4386
4539
|
this.actionsForCompletelyDestroy();
|
|
4387
4540
|
}
|
|
4388
4541
|
else if (this.umdMode && this.container.childElementCount) {
|
|
4389
4542
|
cloneContainer(this.container, this.source.html, false);
|
|
4390
4543
|
}
|
|
4544
|
+
if (this.umdMode) {
|
|
4545
|
+
(_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.recordUmdSnapshot();
|
|
4546
|
+
}
|
|
4391
4547
|
/**
|
|
4392
4548
|
* this.container maybe contains micro-app element, stop sandbox should exec after cloneContainer
|
|
4393
4549
|
* NOTE:
|
|
4394
4550
|
* 1. if destroy is true, clear route state
|
|
4395
4551
|
* 2. umd mode and keep-alive will not clear EventSource
|
|
4396
4552
|
*/
|
|
4397
|
-
(
|
|
4553
|
+
(_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.stop(this.umdMode, this.keepRouteState && !destroy, !this.umdMode || destroy);
|
|
4398
4554
|
if (!getActiveApps().length) {
|
|
4399
4555
|
releasePatchSetAttribute();
|
|
4400
4556
|
}
|
|
@@ -4709,7 +4865,7 @@ function defineElement(tagName) {
|
|
|
4709
4865
|
app.isPrefetch = false;
|
|
4710
4866
|
defer(() => {
|
|
4711
4867
|
var _a;
|
|
4712
|
-
return app.mount((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this, this.getDisposeResult('inline'), this.getBaseRouteCompatible(), this.getDisposeResult('keep-router-state'), this.getDefaultPageValue(), this.getDisposeResult('hidden-router'));
|
|
4868
|
+
return app.mount((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this, this.getDisposeResult('inline'), this.getBaseRouteCompatible(), this.getDisposeResult('keep-router-state'), this.getDefaultPageValue(), this.getDisposeResult('hidden-router'), this.getDisposeResult('disable-patch-request'));
|
|
4713
4869
|
});
|
|
4714
4870
|
}
|
|
4715
4871
|
// create app instance
|
|
@@ -4735,6 +4891,7 @@ function defineElement(tagName) {
|
|
|
4735
4891
|
keepRouteState: this.getDisposeResult('keep-router-state'),
|
|
4736
4892
|
defaultPage: this.getDefaultPageValue(),
|
|
4737
4893
|
hiddenRouter: this.getDisposeResult('hidden-router'),
|
|
4894
|
+
disablePatchRequest: this.getDisposeResult('disable-patch-request'),
|
|
4738
4895
|
});
|
|
4739
4896
|
appInstanceMap.set(this.appName, instance);
|
|
4740
4897
|
}
|
|
@@ -5084,6 +5241,7 @@ class MicroApp extends EventCenterForBaseApp {
|
|
|
5084
5241
|
this['disable-scopecss'] = (_a = options['disable-scopecss']) !== null && _a !== void 0 ? _a : options.disableScopecss;
|
|
5085
5242
|
this['disable-sandbox'] = (_b = options['disable-sandbox']) !== null && _b !== void 0 ? _b : options.disableSandbox;
|
|
5086
5243
|
this['disable-memory-router'] = options['disable-memory-router'];
|
|
5244
|
+
this['disable-patch-request'] = options['disable-patch-request'];
|
|
5087
5245
|
this['keep-router-state'] = options['keep-router-state'];
|
|
5088
5246
|
this['hidden-router'] = options['hidden-router'];
|
|
5089
5247
|
this.esmodule = options.esmodule;
|