@micro-zoe/micro-app 0.3.3 → 0.4.0

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,6 +1,23 @@
1
- const rawWindow = new Function('return window')();
2
- const rawDocument = new Function('return document')();
3
- const version = '0.3.3';
1
+ const version = '0.4.0';
2
+ const isBrowser = typeof window !== 'undefined';
3
+ const globalThis = (function () {
4
+ let gt;
5
+ if (typeof global !== 'undefined') {
6
+ gt = global;
7
+ }
8
+ else if (typeof self !== 'undefined') {
9
+ gt = self;
10
+ }
11
+ else {
12
+ try {
13
+ gt = Function('return this')();
14
+ }
15
+ catch (e) {
16
+ throw new Error('global object is unavailable in this environment');
17
+ }
18
+ }
19
+ return gt;
20
+ })();
4
21
  /**
5
22
  * format error log
6
23
  * @param msg message
@@ -81,7 +98,7 @@ function getEffectivePath(url) {
81
98
  * @param baseURI base url(app.url)
82
99
  */
83
100
  function CompletionPath(path, baseURI) {
84
- if (/^((((ht|f)tps?)|file):)?\/\//.test(path))
101
+ if (/^((((ht|f)tps?)|file):)?\/\//.test(path) || /^(data|blob):/.test(path))
85
102
  return path;
86
103
  return new URL(path, getEffectivePath(addProtocol(baseURI))).toString();
87
104
  }
@@ -149,7 +166,7 @@ function unique(array) {
149
166
  }, Object.create(null));
150
167
  }
151
168
  // requestIdleCallback polyfill
152
- const requestIdleCallback = window.requestIdleCallback ||
169
+ const requestIdleCallback = globalThis.requestIdleCallback ||
153
170
  function (fn) {
154
171
  const lastTime = Date.now();
155
172
  return setTimeout(function () {
@@ -188,7 +205,7 @@ function isFunction(target) {
188
205
  * Create pure elements
189
206
  */
190
207
  function pureCreateElement(tagName, options) {
191
- const element = rawDocument.createElement(tagName, options);
208
+ const element = document.createElement(tagName, options);
192
209
  if (element.__MICRO_APP_NAME__)
193
210
  delete element.__MICRO_APP_NAME__;
194
211
  return element;
@@ -234,6 +251,83 @@ var lifeCycles;
234
251
  lifeCycles["ERROR"] = "error";
235
252
  })(lifeCycles || (lifeCycles = {}));
236
253
 
254
+ const globalEnv = {};
255
+ function initGloalEnv() {
256
+ if (isBrowser) {
257
+ /**
258
+ * save patch raw methods
259
+ * pay attention to this binding
260
+ */
261
+ const rawSetAttribute = Element.prototype.setAttribute;
262
+ const rawAppendChild = Node.prototype.appendChild;
263
+ const rawInsertBefore = Node.prototype.insertBefore;
264
+ const rawReplaceChild = Node.prototype.replaceChild;
265
+ const rawRemoveChild = Node.prototype.removeChild;
266
+ const rawAppend = Element.prototype.append;
267
+ const rawPrepend = Element.prototype.prepend;
268
+ const rawCreateElement = Document.prototype.createElement;
269
+ const rawCreateElementNS = Document.prototype.createElementNS;
270
+ const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
271
+ const rawQuerySelector = Document.prototype.querySelector;
272
+ const rawQuerySelectorAll = Document.prototype.querySelectorAll;
273
+ const rawGetElementById = Document.prototype.getElementById;
274
+ const rawGetElementsByClassName = Document.prototype.getElementsByClassName;
275
+ const rawGetElementsByTagName = Document.prototype.getElementsByTagName;
276
+ const rawGetElementsByName = Document.prototype.getElementsByName;
277
+ const rawWindow = Function('return window')();
278
+ const rawDocument = Function('return document')();
279
+ const supportModuleScript = isSupportModuleScript();
280
+ const templateStyle = rawDocument.body.querySelector('#micro-app-template-style');
281
+ /**
282
+ * save effect raw methods
283
+ * pay attention to this binding, especially setInterval, setTimeout, clearInterval, clearTimeout
284
+ */
285
+ const rawWindowAddEventListener = rawWindow.addEventListener;
286
+ const rawWindowRemoveEventListener = rawWindow.removeEventListener;
287
+ const rawSetInterval = rawWindow.setInterval;
288
+ const rawSetTimeout = rawWindow.setTimeout;
289
+ const rawClearInterval = rawWindow.clearInterval;
290
+ const rawClearTimeout = rawWindow.clearTimeout;
291
+ const rawDocumentAddEventListener = rawDocument.addEventListener;
292
+ const rawDocumentRemoveEventListener = rawDocument.removeEventListener;
293
+ // mark current application as base application
294
+ window.__MICRO_APP_BASE_APPLICATION__ = true;
295
+ Object.assign(globalEnv, {
296
+ // source/patch
297
+ rawSetAttribute,
298
+ rawAppendChild,
299
+ rawInsertBefore,
300
+ rawReplaceChild,
301
+ rawRemoveChild,
302
+ rawAppend,
303
+ rawPrepend,
304
+ rawCreateElement,
305
+ rawCreateElementNS,
306
+ rawCreateDocumentFragment,
307
+ rawQuerySelector,
308
+ rawQuerySelectorAll,
309
+ rawGetElementById,
310
+ rawGetElementsByClassName,
311
+ rawGetElementsByTagName,
312
+ rawGetElementsByName,
313
+ // common global vars
314
+ rawWindow,
315
+ rawDocument,
316
+ supportModuleScript,
317
+ templateStyle,
318
+ // sandbox/effect
319
+ rawWindowAddEventListener,
320
+ rawWindowRemoveEventListener,
321
+ rawSetInterval,
322
+ rawSetTimeout,
323
+ rawClearInterval,
324
+ rawClearTimeout,
325
+ rawDocumentAddEventListener,
326
+ rawDocumentRemoveEventListener,
327
+ });
328
+ }
329
+ }
330
+
237
331
  // https://developer.mozilla.org/zh-CN/docs/Web/API/CSSRule
238
332
  var CSSRuleType;
239
333
  (function (CSSRuleType) {
@@ -284,7 +378,7 @@ function scopedStyleRule(rule, prefix) {
284
378
  */
285
379
  function scopedHost(cssText, baseURI, textContent, linkpath) {
286
380
  return cssText.replace(/url\(["']?([^)"']+)["']?\)/gm, (all, $1) => {
287
- if (/^data:/.test($1)) {
381
+ if (/^(data|blob):/.test($1)) {
288
382
  return all;
289
383
  }
290
384
  else if (/^(https?:)?\/\//.test($1)) {
@@ -361,7 +455,6 @@ function commonAction(templateStyle, styleElement, originContent, prefix, baseUR
361
455
  }
362
456
  styleElement.textContent = result;
363
457
  }
364
- let templateStyle = rawDocument.body.querySelector('#micro-app-template-style');
365
458
  /**
366
459
  * scopedCSS
367
460
  * @param styleElement target style element
@@ -371,10 +464,11 @@ function scopedCSS(styleElement, appName) {
371
464
  const app = appInstanceMap.get(appName);
372
465
  if (app === null || app === void 0 ? void 0 : app.scopecss) {
373
466
  const prefix = `${microApp.tagName}[name=${appName}]`;
467
+ let templateStyle = globalEnv.templateStyle;
374
468
  if (!templateStyle) {
375
- templateStyle = pureCreateElement('style');
469
+ globalEnv.templateStyle = templateStyle = pureCreateElement('style');
376
470
  templateStyle.setAttribute('id', 'micro-app-template-style');
377
- rawDocument.body.appendChild(templateStyle);
471
+ globalEnv.rawDocument.body.appendChild(templateStyle);
378
472
  templateStyle.sheet.disabled = true;
379
473
  }
380
474
  if (styleElement.textContent) {
@@ -582,7 +676,6 @@ function formatHTMLStyleAfterUmdInit(tempHTML, appName) {
582
676
 
583
677
  // Global scripts, reuse across apps
584
678
  const globalScripts = new Map();
585
- const supportModuleScript = isSupportModuleScript();
586
679
  /**
587
680
  * Extract script elements
588
681
  * @param script script element
@@ -596,8 +689,12 @@ function extractScriptElement(script, parent, app, isDynamic = false) {
596
689
  if (script.hasAttribute('exclude')) {
597
690
  replaceComment = document.createComment('script element with exclude attribute ignored by micro-app');
598
691
  }
599
- else if ((supportModuleScript && script.noModule) ||
600
- (!supportModuleScript && script.type === 'module')) {
692
+ else if ((script.type && !['text/javascript', 'text/ecmascript', 'application/javascript', 'application/ecmascript', 'module'].includes(script.type)) ||
693
+ script.hasAttribute('ignore')) {
694
+ return null;
695
+ }
696
+ else if ((globalEnv.supportModuleScript && script.noModule) ||
697
+ (!globalEnv.supportModuleScript && script.type === 'module')) {
601
698
  replaceComment = document.createComment(`${script.noModule ? 'noModule' : 'module'} script ignored by micro-app`);
602
699
  }
603
700
  else if (src) { // remote script
@@ -643,7 +740,7 @@ function extractScriptElement(script, parent, app, isDynamic = false) {
643
740
  if (isDynamic) {
644
741
  return { replaceComment };
645
742
  }
646
- else {
743
+ else if (replaceComment) {
647
744
  return parent.replaceChild(replaceComment, script);
648
745
  }
649
746
  }
@@ -697,8 +794,9 @@ function fetchScriptSuccess(url, info, data) {
697
794
  * Execute js in the mount lifecycle
698
795
  * @param scriptList script list
699
796
  * @param app app
797
+ * @param callback callback for umd mode
700
798
  */
701
- function execScripts(scriptList, app) {
799
+ function execScripts(scriptList, app, callback) {
702
800
  const scriptListEntries = Array.from(scriptList.entries());
703
801
  const deferScriptPromise = [];
704
802
  const deferScriptInfo = [];
@@ -722,12 +820,47 @@ function execScripts(scriptList, app) {
722
820
  Promise.all(deferScriptPromise).then((res) => {
723
821
  res.forEach((code, index) => {
724
822
  const [url, info] = deferScriptInfo[index];
725
- runScript(url, info.code = info.code || code, app, info.module, false);
823
+ runScript(url, info.code = info.code || code, app, info.module, false, callback);
726
824
  });
825
+ callback();
727
826
  }).catch((err) => {
728
827
  logError(err);
828
+ callback();
729
829
  });
730
830
  }
831
+ else {
832
+ callback();
833
+ }
834
+ }
835
+ /**
836
+ * run code
837
+ * @param url script address
838
+ * @param code js code
839
+ * @param app app
840
+ * @param module type='module' of script
841
+ * @param isDynamic dynamically created script
842
+ * @param callback callback from execScripts for first exec
843
+ */
844
+ function runScript(url, code, app, module, isDynamic, callback) {
845
+ var _a;
846
+ try {
847
+ code = bindScope(url, code, app);
848
+ if (app.inline) {
849
+ const scriptElement = pureCreateElement('script');
850
+ setInlinScriptContent(url, code, module, scriptElement, callback);
851
+ if (isDynamic)
852
+ return scriptElement;
853
+ (_a = app.container) === null || _a === void 0 ? void 0 : _a.querySelector('micro-app-body').appendChild(scriptElement);
854
+ }
855
+ else {
856
+ Function(code)();
857
+ if (isDynamic)
858
+ return document.createComment('dynamic script extract by micro-app');
859
+ }
860
+ }
861
+ catch (e) {
862
+ console.error('[micro-app from runScript]', e);
863
+ }
731
864
  }
732
865
  /**
733
866
  * Get dynamically created remote script
@@ -756,20 +889,18 @@ function runDynamicScript(url, info, app, originScript) {
756
889
  else {
757
890
  replaceElement = document.createComment(`dynamic script with src='${url}' extract by micro-app`);
758
891
  }
759
- fetchSource(url, app.name).then((data) => {
760
- info.code = data;
892
+ fetchSource(url, app.name).then((code) => {
893
+ info.code = code;
761
894
  app.source.scripts.set(url, info);
762
895
  if (info.isGlobal)
763
- globalScripts.set(url, data);
896
+ globalScripts.set(url, code);
764
897
  try {
765
- data = bindScope(url, data, app);
898
+ code = bindScope(url, code, app);
766
899
  if (app.inline) {
767
- if (info.module)
768
- replaceElement.setAttribute('type', 'module');
769
- replaceElement.textContent = data;
900
+ setInlinScriptContent(url, code, info.module, replaceElement);
770
901
  }
771
902
  else {
772
- Function(data)();
903
+ Function(code)();
773
904
  }
774
905
  }
775
906
  catch (e) {
@@ -783,34 +914,24 @@ function runDynamicScript(url, info, app, originScript) {
783
914
  return replaceElement;
784
915
  }
785
916
  /**
786
- * run code
917
+ * common handle for inline script
787
918
  * @param url script address
788
919
  * @param code js code
789
- * @param app app
790
920
  * @param module type='module' of script
791
- * @param isDynamic dynamically created script
921
+ * @param scriptElement target script element
922
+ * @param callback callback from execScripts for first exec
792
923
  */
793
- function runScript(url, code, app, module, isDynamic) {
794
- var _a;
795
- try {
796
- code = bindScope(url, code, app);
797
- if (app.inline) {
798
- const script = pureCreateElement('script');
799
- if (module)
800
- script.setAttribute('type', 'module');
801
- script.textContent = code;
802
- if (isDynamic)
803
- return script;
804
- (_a = app.container) === null || _a === void 0 ? void 0 : _a.querySelector('micro-app-body').appendChild(script);
805
- }
806
- else {
807
- Function(code)();
808
- if (isDynamic)
809
- return document.createComment('dynamic script extract by micro-app');
810
- }
924
+ function setInlinScriptContent(url, code, module, scriptElement, callback) {
925
+ if (module) {
926
+ // module script is async, transform it to a blob for subsequent operations
927
+ const blob = new Blob([code], { type: 'text/javascript;charset=utf-8' });
928
+ scriptElement.src = URL.createObjectURL(blob);
929
+ scriptElement.setAttribute('type', 'module');
930
+ scriptElement.setAttribute('originSrc', url);
931
+ callback && (scriptElement.onload = callback);
811
932
  }
812
- catch (e) {
813
- console.error('[micro-app from runScript]', e);
933
+ else {
934
+ scriptElement.textContent = code;
814
935
  }
815
936
  }
816
937
  /**
@@ -824,7 +945,7 @@ function bindScope(url, code, app) {
824
945
  code = usePlugins(url, code, app.name, microApp.plugins);
825
946
  }
826
947
  if (app.sandBox) {
827
- rawWindow.__MICRO_APP_PROXY_WINDOW__ = app.sandBox.proxyWindow;
948
+ globalEnv.rawWindow.__MICRO_APP_PROXY_WINDOW__ = app.sandBox.proxyWindow;
828
949
  return `;(function(window, self){with(window){;${code}\n}}).call(window.__MICRO_APP_PROXY_WINDOW__, window.__MICRO_APP_PROXY_WINDOW__, window.__MICRO_APP_PROXY_WINDOW__);`;
829
950
  }
830
951
  return code;
@@ -855,23 +976,6 @@ function usePlugins(url, code, appName, plugins) {
855
976
  return code;
856
977
  }
857
978
 
858
- // save raw methods
859
- const rawSetAttribute = Element.prototype.setAttribute;
860
- const rawAppendChild = Node.prototype.appendChild;
861
- const rawInsertBefore = Node.prototype.insertBefore;
862
- const rawReplaceChild = Node.prototype.replaceChild;
863
- const rawRemoveChild = Node.prototype.removeChild;
864
- const rawAppend = Element.prototype.append;
865
- const rawPrepend = Element.prototype.prepend;
866
- const rawCreateElement = Document.prototype.createElement;
867
- const rawCreateElementNS = Document.prototype.createElementNS;
868
- const rawCreateDocumentFragment = Document.prototype.createDocumentFragment;
869
- const rawQuerySelector = Document.prototype.querySelector;
870
- const rawQuerySelectorAll = Document.prototype.querySelectorAll;
871
- const rawGetElementById = Document.prototype.getElementById;
872
- const rawGetElementsByClassName = Document.prototype.getElementsByClassName;
873
- const rawGetElementsByTagName = Document.prototype.getElementsByTagName;
874
- const rawGetElementsByName = Document.prototype.getElementsByName;
875
979
  // Record element and map element
876
980
  const dynamicElementInMicroAppMap = new WeakMap();
877
981
  /**
@@ -887,7 +991,7 @@ function handleNewNode(parent, child, app) {
887
991
  dynamicElementInMicroAppMap.set(child, replaceComment);
888
992
  return replaceComment;
889
993
  }
890
- else if (app.scopecss) {
994
+ else if (app.scopecss && !child.hasAttribute('ignore')) {
891
995
  return scopedCSS(child, app.name);
892
996
  }
893
997
  return child;
@@ -898,7 +1002,7 @@ function handleNewNode(parent, child, app) {
898
1002
  dynamicElementInMicroAppMap.set(child, linkReplaceComment);
899
1003
  return linkReplaceComment;
900
1004
  }
901
- else if (!app.scopecss) {
1005
+ else if (!app.scopecss || child.hasAttribute('ignore')) {
902
1006
  return child;
903
1007
  }
904
1008
  const { url, info } = extractLinkFromHtml(child, parent, app, null, true);
@@ -916,7 +1020,7 @@ function handleNewNode(parent, child, app) {
916
1020
  return child;
917
1021
  }
918
1022
  else if (child instanceof HTMLScriptElement) {
919
- const { replaceComment, url, info } = extractScriptElement(child, parent, app, true);
1023
+ const { replaceComment, url, info } = extractScriptElement(child, parent, app, true) || {};
920
1024
  if (url && info) {
921
1025
  if (info.code) { // inline script
922
1026
  const replaceElement = runScript(url, info.code, app, info.module, true);
@@ -929,10 +1033,11 @@ function handleNewNode(parent, child, app) {
929
1033
  return replaceElement;
930
1034
  }
931
1035
  }
932
- else {
1036
+ else if (replaceComment) {
933
1037
  dynamicElementInMicroAppMap.set(child, replaceComment);
934
1038
  return replaceComment;
935
1039
  }
1040
+ return child;
936
1041
  }
937
1042
  return child;
938
1043
  }
@@ -956,15 +1061,15 @@ function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild
956
1061
  * 2. When removeChild, targetChild may not be in microAppHead or head
957
1062
  */
958
1063
  if (passiveChild && !microAppHead.contains(passiveChild)) {
959
- return rawAppendChild.call(microAppHead, targetChild);
1064
+ return globalEnv.rawAppendChild.call(microAppHead, targetChild);
960
1065
  }
961
- else if (rawMethod === rawRemoveChild && !microAppHead.contains(targetChild)) {
1066
+ else if (rawMethod === globalEnv.rawRemoveChild && !microAppHead.contains(targetChild)) {
962
1067
  if (parent.contains(targetChild)) {
963
1068
  return rawMethod.call(parent, targetChild);
964
1069
  }
965
1070
  return targetChild;
966
1071
  }
967
- else if (rawMethod === rawAppend || rawMethod === rawPrepend) {
1072
+ else if (rawMethod === globalEnv.rawAppend || rawMethod === globalEnv.rawPrepend) {
968
1073
  return rawMethod.call(microAppHead, targetChild);
969
1074
  }
970
1075
  return rawMethod.call(microAppHead, targetChild, passiveChild);
@@ -972,20 +1077,20 @@ function invokePrototypeMethod(app, rawMethod, parent, targetChild, passiveChild
972
1077
  else if (parent === document.body) {
973
1078
  const microAppBody = app.container.querySelector('micro-app-body');
974
1079
  if (passiveChild && !microAppBody.contains(passiveChild)) {
975
- return rawAppendChild.call(microAppBody, targetChild);
1080
+ return globalEnv.rawAppendChild.call(microAppBody, targetChild);
976
1081
  }
977
- else if (rawMethod === rawRemoveChild && !microAppBody.contains(targetChild)) {
1082
+ else if (rawMethod === globalEnv.rawRemoveChild && !microAppBody.contains(targetChild)) {
978
1083
  if (parent.contains(targetChild)) {
979
1084
  return rawMethod.call(parent, targetChild);
980
1085
  }
981
1086
  return targetChild;
982
1087
  }
983
- else if (rawMethod === rawAppend || rawMethod === rawPrepend) {
1088
+ else if (rawMethod === globalEnv.rawAppend || rawMethod === globalEnv.rawPrepend) {
984
1089
  return rawMethod.call(microAppBody, targetChild);
985
1090
  }
986
1091
  return rawMethod.call(microAppBody, targetChild, passiveChild);
987
1092
  }
988
- else if (rawMethod === rawAppend || rawMethod === rawPrepend) {
1093
+ else if (rawMethod === globalEnv.rawAppend || rawMethod === globalEnv.rawPrepend) {
989
1094
  return rawMethod.call(parent, targetChild);
990
1095
  }
991
1096
  return rawMethod.call(parent, targetChild, passiveChild);
@@ -1000,7 +1105,7 @@ function getMappingNode(node) {
1000
1105
  * @param parent parent node
1001
1106
  * @param newChild new node
1002
1107
  * @param passiveChild passive node
1003
- * @param rawMethod raw method
1108
+ * @param rawMethodraw method
1004
1109
  */
1005
1110
  function commonElementHander(parent, newChild, passiveChild, rawMethod) {
1006
1111
  if (newChild === null || newChild === void 0 ? void 0 : newChild.__MICRO_APP_NAME__) {
@@ -1008,12 +1113,12 @@ function commonElementHander(parent, newChild, passiveChild, rawMethod) {
1008
1113
  if (app === null || app === void 0 ? void 0 : app.container) {
1009
1114
  return invokePrototypeMethod(app, rawMethod, parent, handleNewNode(parent, newChild, app), passiveChild && getMappingNode(passiveChild));
1010
1115
  }
1011
- else if (rawMethod === rawAppend || rawMethod === rawPrepend) {
1116
+ else if (rawMethod === globalEnv.rawAppend || rawMethod === globalEnv.rawPrepend) {
1012
1117
  return rawMethod.call(parent, newChild);
1013
1118
  }
1014
1119
  return rawMethod.call(parent, newChild, passiveChild);
1015
1120
  }
1016
- else if (rawMethod === rawAppend || rawMethod === rawPrepend) {
1121
+ else if (rawMethod === globalEnv.rawAppend || rawMethod === globalEnv.rawPrepend) {
1017
1122
  const appName = getCurrentAppName();
1018
1123
  if (!(newChild instanceof Node) && appName) {
1019
1124
  const app = appInstanceMap.get(appName);
@@ -1057,34 +1162,34 @@ function patchElementPrototypeMethods() {
1057
1162
  this.__MICRO_APP_NAME__ &&
1058
1163
  appInstanceMap.has(this.__MICRO_APP_NAME__)) {
1059
1164
  const app = appInstanceMap.get(this.__MICRO_APP_NAME__);
1060
- rawSetAttribute.call(this, key, CompletionPath(value, app.url));
1165
+ globalEnv.rawSetAttribute.call(this, key, CompletionPath(value, app.url));
1061
1166
  }
1062
1167
  else {
1063
- rawSetAttribute.call(this, key, value);
1168
+ globalEnv.rawSetAttribute.call(this, key, value);
1064
1169
  }
1065
1170
  };
1066
1171
  // prototype methods of add element👇
1067
1172
  Node.prototype.appendChild = function appendChild(newChild) {
1068
- return commonElementHander(this, newChild, null, rawAppendChild);
1173
+ return commonElementHander(this, newChild, null, globalEnv.rawAppendChild);
1069
1174
  };
1070
1175
  Node.prototype.insertBefore = function insertBefore(newChild, refChild) {
1071
- return commonElementHander(this, newChild, refChild, rawInsertBefore);
1176
+ return commonElementHander(this, newChild, refChild, globalEnv.rawInsertBefore);
1072
1177
  };
1073
1178
  Node.prototype.replaceChild = function replaceChild(newChild, oldChild) {
1074
- return commonElementHander(this, newChild, oldChild, rawReplaceChild);
1179
+ return commonElementHander(this, newChild, oldChild, globalEnv.rawReplaceChild);
1075
1180
  };
1076
1181
  Element.prototype.append = function append(...nodes) {
1077
1182
  let i = 0;
1078
1183
  const length = nodes.length;
1079
1184
  while (i < length) {
1080
- commonElementHander(this, nodes[i], null, rawAppend);
1185
+ commonElementHander(this, nodes[i], null, globalEnv.rawAppend);
1081
1186
  i++;
1082
1187
  }
1083
1188
  };
1084
1189
  Element.prototype.prepend = function prepend(...nodes) {
1085
1190
  let i = nodes.length;
1086
1191
  while (i > 0) {
1087
- commonElementHander(this, nodes[i - 1], null, rawPrepend);
1192
+ commonElementHander(this, nodes[i - 1], null, globalEnv.rawPrepend);
1088
1193
  i--;
1089
1194
  }
1090
1195
  };
@@ -1093,11 +1198,11 @@ function patchElementPrototypeMethods() {
1093
1198
  if (oldChild === null || oldChild === void 0 ? void 0 : oldChild.__MICRO_APP_NAME__) {
1094
1199
  const app = appInstanceMap.get(oldChild.__MICRO_APP_NAME__);
1095
1200
  if (app === null || app === void 0 ? void 0 : app.container) {
1096
- return invokePrototypeMethod(app, rawRemoveChild, this, getMappingNode(oldChild));
1201
+ return invokePrototypeMethod(app, globalEnv.rawRemoveChild, this, getMappingNode(oldChild));
1097
1202
  }
1098
- return rawRemoveChild.call(this, oldChild);
1203
+ return globalEnv.rawRemoveChild.call(this, oldChild);
1099
1204
  }
1100
- return rawRemoveChild.call(this, oldChild);
1205
+ return globalEnv.rawRemoveChild.call(this, oldChild);
1101
1206
  };
1102
1207
  }
1103
1208
  /**
@@ -1113,17 +1218,18 @@ function markElement(element) {
1113
1218
  }
1114
1219
  // methods of document
1115
1220
  function patchDocument() {
1221
+ const rawDocument = globalEnv.rawDocument;
1116
1222
  // create element 👇
1117
1223
  Document.prototype.createElement = function createElement(tagName, options) {
1118
- const element = rawCreateElement.call(rawDocument, tagName, options);
1224
+ const element = globalEnv.rawCreateElement.call(rawDocument, tagName, options);
1119
1225
  return markElement(element);
1120
1226
  };
1121
1227
  Document.prototype.createElementNS = function createElementNS(namespaceURI, name, options) {
1122
- const element = rawCreateElementNS.call(rawDocument, namespaceURI, name, options);
1228
+ const element = globalEnv.rawCreateElementNS.call(rawDocument, namespaceURI, name, options);
1123
1229
  return markElement(element);
1124
1230
  };
1125
1231
  Document.prototype.createDocumentFragment = function createDocumentFragment() {
1126
- const element = rawCreateDocumentFragment.call(rawDocument);
1232
+ const element = globalEnv.rawCreateDocumentFragment.call(rawDocument);
1127
1233
  return markElement(element);
1128
1234
  };
1129
1235
  // query element👇
@@ -1131,7 +1237,7 @@ function patchDocument() {
1131
1237
  var _a, _b, _c;
1132
1238
  const appName = getCurrentAppName();
1133
1239
  if (!appName || selectors === 'head' || selectors === 'body' || selectors === 'html') {
1134
- return rawQuerySelector.call(rawDocument, selectors);
1240
+ return globalEnv.rawQuerySelector.call(rawDocument, selectors);
1135
1241
  }
1136
1242
  return (_c = (_b = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.container) === null || _b === void 0 ? void 0 : _b.querySelector(selectors)) !== null && _c !== void 0 ? _c : null;
1137
1243
  }
@@ -1139,7 +1245,7 @@ function patchDocument() {
1139
1245
  var _a, _b, _c;
1140
1246
  const appName = getCurrentAppName();
1141
1247
  if (!appName || selectors === 'head' || selectors === 'body' || selectors === 'html') {
1142
- return rawQuerySelectorAll.call(rawDocument, selectors);
1248
+ return globalEnv.rawQuerySelectorAll.call(rawDocument, selectors);
1143
1249
  }
1144
1250
  return (_c = (_b = (_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.container) === null || _b === void 0 ? void 0 : _b.querySelectorAll(selectors)) !== null && _c !== void 0 ? _c : [];
1145
1251
  }
@@ -1149,14 +1255,14 @@ function patchDocument() {
1149
1255
  Document.prototype.getElementById = function getElementById(key) {
1150
1256
  const appName = getCurrentAppName();
1151
1257
  if (!appName || /^\d/.test(key)) {
1152
- return rawGetElementById.call(rawDocument, key);
1258
+ return globalEnv.rawGetElementById.call(rawDocument, key);
1153
1259
  }
1154
1260
  return querySelector(`#${key}`);
1155
1261
  };
1156
1262
  Document.prototype.getElementsByClassName = function getElementsByClassName(key) {
1157
1263
  const appName = getCurrentAppName();
1158
1264
  if (!appName || /^\d/.test(key)) {
1159
- return rawGetElementsByClassName.call(rawDocument, key);
1265
+ return globalEnv.rawGetElementsByClassName.call(rawDocument, key);
1160
1266
  }
1161
1267
  return querySelectorAll(`.${key}`);
1162
1268
  };
@@ -1168,40 +1274,40 @@ function patchDocument() {
1168
1274
  /^head$/i.test(key) ||
1169
1275
  /^html$/i.test(key) ||
1170
1276
  (!((_a = appInstanceMap.get(appName)) === null || _a === void 0 ? void 0 : _a.inline) && /^script$/i.test(key))) {
1171
- return rawGetElementsByTagName.call(rawDocument, key);
1277
+ return globalEnv.rawGetElementsByTagName.call(rawDocument, key);
1172
1278
  }
1173
1279
  return querySelectorAll(key);
1174
1280
  };
1175
1281
  Document.prototype.getElementsByName = function getElementsByName(key) {
1176
1282
  const appName = getCurrentAppName();
1177
1283
  if (!appName || /^\d/.test(key)) {
1178
- return rawGetElementsByName.call(rawDocument, key);
1284
+ return globalEnv.rawGetElementsByName.call(rawDocument, key);
1179
1285
  }
1180
1286
  return querySelectorAll(`[name=${key}]`);
1181
1287
  };
1182
1288
  }
1183
1289
  function releasePatchDocument() {
1184
- Document.prototype.createElement = rawCreateElement;
1185
- Document.prototype.createElementNS = rawCreateElementNS;
1186
- Document.prototype.createDocumentFragment = rawCreateDocumentFragment;
1187
- Document.prototype.querySelector = rawQuerySelector;
1188
- Document.prototype.querySelectorAll = rawQuerySelectorAll;
1189
- Document.prototype.getElementById = rawGetElementById;
1190
- Document.prototype.getElementsByClassName = rawGetElementsByClassName;
1191
- Document.prototype.getElementsByTagName = rawGetElementsByTagName;
1192
- Document.prototype.getElementsByName = rawGetElementsByName;
1290
+ Document.prototype.createElement = globalEnv.rawCreateElement;
1291
+ Document.prototype.createElementNS = globalEnv.rawCreateElementNS;
1292
+ Document.prototype.createDocumentFragment = globalEnv.rawCreateDocumentFragment;
1293
+ Document.prototype.querySelector = globalEnv.rawQuerySelector;
1294
+ Document.prototype.querySelectorAll = globalEnv.rawQuerySelectorAll;
1295
+ Document.prototype.getElementById = globalEnv.rawGetElementById;
1296
+ Document.prototype.getElementsByClassName = globalEnv.rawGetElementsByClassName;
1297
+ Document.prototype.getElementsByTagName = globalEnv.rawGetElementsByTagName;
1298
+ Document.prototype.getElementsByName = globalEnv.rawGetElementsByName;
1193
1299
  }
1194
1300
  // release patch
1195
1301
  function releasePatches() {
1196
1302
  setCurrentAppName(null);
1197
1303
  releasePatchDocument();
1198
- Element.prototype.setAttribute = rawSetAttribute;
1199
- Node.prototype.appendChild = rawAppendChild;
1200
- Node.prototype.insertBefore = rawInsertBefore;
1201
- Node.prototype.replaceChild = rawReplaceChild;
1202
- Node.prototype.removeChild = rawRemoveChild;
1203
- Element.prototype.append = rawAppend;
1204
- Element.prototype.prepend = rawPrepend;
1304
+ Element.prototype.setAttribute = globalEnv.rawSetAttribute;
1305
+ Node.prototype.appendChild = globalEnv.rawAppendChild;
1306
+ Node.prototype.insertBefore = globalEnv.rawInsertBefore;
1307
+ Node.prototype.replaceChild = globalEnv.rawReplaceChild;
1308
+ Node.prototype.removeChild = globalEnv.rawRemoveChild;
1309
+ Element.prototype.append = globalEnv.rawAppend;
1310
+ Element.prototype.prepend = globalEnv.rawPrepend;
1205
1311
  }
1206
1312
  // Set the style of micro-app-head and micro-app-body
1207
1313
  let hasRejectMicroAppStyle = false;
@@ -1211,7 +1317,7 @@ function rejectMicroAppStyle() {
1211
1317
  const style = pureCreateElement('style');
1212
1318
  style.setAttribute('type', 'text/css');
1213
1319
  style.textContent = `\n${microApp.tagName}, micro-app-body { display: block; } \nmicro-app-head { display: none; }`;
1214
- rawDocument.head.appendChild(style);
1320
+ globalEnv.rawDocument.head.appendChild(style);
1215
1321
  }
1216
1322
  }
1217
1323
 
@@ -1271,7 +1377,8 @@ function dispatchUnmountToMicroApp(appName) {
1271
1377
  window.dispatchEvent(event);
1272
1378
  }
1273
1379
 
1274
- function unmountAppInline() {
1380
+ function unmountNestedApp() {
1381
+ replaseUnmountOfNestedApp();
1275
1382
  appInstanceMap.forEach(app => {
1276
1383
  let element = app.container;
1277
1384
  if (element) {
@@ -1282,256 +1389,273 @@ function unmountAppInline() {
1282
1389
  element.disconnectedCallback();
1283
1390
  }
1284
1391
  });
1285
- appInstanceMap.clear();
1392
+ if (!window.__MICRO_APP_UMD_MODE__)
1393
+ appInstanceMap.clear();
1394
+ if (elementInstanceMap.size) {
1395
+ elementInstanceMap.clear();
1396
+ releasePatches();
1397
+ }
1286
1398
  }
1287
1399
  // if micro-app run in micro application, delete all next generation application when unmount event received
1288
- function listenUmountAppInline() {
1400
+ function listenUmountOfNestedApp() {
1289
1401
  if (window.__MICRO_APP_ENVIRONMENT__) {
1290
- window.addEventListener('unmount', unmountAppInline, false);
1402
+ window.addEventListener('unmount', unmountNestedApp, false);
1291
1403
  }
1292
1404
  }
1293
1405
  // release listener
1294
- function replaseUnmountAppInline() {
1406
+ function replaseUnmountOfNestedApp() {
1295
1407
  if (window.__MICRO_APP_ENVIRONMENT__) {
1296
- window.removeEventListener('unmount', unmountAppInline, false);
1408
+ window.removeEventListener('unmount', unmountNestedApp, false);
1297
1409
  }
1298
1410
  }
1299
1411
 
1300
1412
  // record all micro-app elements
1301
1413
  const elementInstanceMap = new Map();
1302
- class MicroAppElement extends HTMLElement {
1303
- constructor() {
1304
- super();
1305
- this.appName = '';
1306
- this.appUrl = '';
1307
- this.version = version;
1308
- this.isWating = false;
1309
- this.cacheData = null;
1310
- /**
1311
- * handle for change of name an url after element inited
1312
- */
1313
- this.handleAttributeUpdate = () => {
1314
- var _a;
1414
+ /**
1415
+ * define element
1416
+ * @param tagName element name
1417
+ */
1418
+ function defineElement(tagName) {
1419
+ class MicroAppElement extends HTMLElement {
1420
+ constructor() {
1421
+ super();
1422
+ this.appName = '';
1423
+ this.appUrl = '';
1424
+ this.version = version;
1315
1425
  this.isWating = false;
1316
- const attrName = this.getAttribute('name');
1317
- const attrUrl = formatURL(this.getAttribute('url'));
1318
- if (this.legalAttribute('name', attrName) && this.legalAttribute('url', attrUrl)) {
1319
- const existApp = appInstanceMap.get(attrName);
1320
- if (attrName !== this.appName && existApp) {
1321
- // handling of cached and non-prefetch apps
1322
- if (appStatus.UNMOUNT !== existApp.getAppStatus() && !existApp.isPrefetch) {
1323
- this.setAttribute('name', this.appName);
1324
- return logError(`an app named ${attrName} already exists`);
1426
+ this.cacheData = null;
1427
+ this.hasConnected = false;
1428
+ /**
1429
+ * handle for change of name an url after element inited
1430
+ */
1431
+ this.handleAttributeUpdate = () => {
1432
+ var _a;
1433
+ this.isWating = false;
1434
+ const attrName = this.getAttribute('name');
1435
+ const attrUrl = formatURL(this.getAttribute('url'));
1436
+ if (this.legalAttribute('name', attrName) && this.legalAttribute('url', attrUrl)) {
1437
+ const existApp = appInstanceMap.get(attrName);
1438
+ if (attrName !== this.appName && existApp) {
1439
+ // handling of cached and non-prefetch apps
1440
+ if (appStatus.UNMOUNT !== existApp.getAppStatus() && !existApp.isPrefetch) {
1441
+ this.setAttribute('name', this.appName);
1442
+ return logError(`an app named ${attrName} already exists`);
1443
+ }
1325
1444
  }
1445
+ if (attrName !== this.appName || attrUrl !== this.appUrl) {
1446
+ this.handleUnmount(attrName === this.appName);
1447
+ this.appName = attrName;
1448
+ this.appUrl = attrUrl;
1449
+ ((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this).innerHTML = '';
1450
+ /**
1451
+ * when existApp not undefined
1452
+ * if attrName and this.appName are equal, existApp has been unmounted
1453
+ * if attrName and this.appName are not equal, existApp is prefetch or unmounted
1454
+ */
1455
+ if (existApp && existApp.url === attrUrl) {
1456
+ // mount app
1457
+ this.handleAppMount(existApp);
1458
+ }
1459
+ else {
1460
+ this.handleCreate();
1461
+ }
1462
+ }
1463
+ }
1464
+ else if (attrName !== this.appName) {
1465
+ this.setAttribute('name', this.appName);
1326
1466
  }
1327
- if (attrName !== this.appName || attrUrl !== this.appUrl) {
1328
- this.handleUnmount(attrName === this.appName);
1329
- this.appName = attrName;
1330
- this.appUrl = attrUrl;
1331
- ((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this).innerHTML = '';
1332
- /**
1333
- * when existApp not undefined
1334
- * if attrName and this.appName are equal, existApp has been unmounted
1335
- * if attrName and this.appName are not equal, existApp is prefetch or unmounted
1336
- */
1337
- if (existApp && existApp.url === attrUrl) {
1338
- // mount app
1339
- this.handleAppMount(existApp);
1467
+ };
1468
+ // cloned node of umd container also trigger constructor, we should skip
1469
+ if (!this.querySelector('micro-app-head')) {
1470
+ this.performWhenFirstCreated();
1471
+ }
1472
+ }
1473
+ static get observedAttributes() {
1474
+ return ['name', 'url'];
1475
+ }
1476
+ // 👇 Configuration
1477
+ // shadowDom: use shadowDOM, default is false
1478
+ // destory: whether delete cache resources when unmount, default is false
1479
+ // inline: whether js runs in inline script mode, default is false
1480
+ // disableScopecss: whether disable css scoped, default is false
1481
+ // disableSandbox: whether disable sandbox, default is false
1482
+ // macro: used to solve the async render problem of vue3, default is false
1483
+ // baseRoute: route prefix, default is ''
1484
+ connectedCallback() {
1485
+ this.hasConnected = true;
1486
+ if (!elementInstanceMap.has(this)) {
1487
+ this.performWhenFirstCreated();
1488
+ }
1489
+ defer(() => dispatchLifecyclesEvent(this, this.appName, lifeCycles.CREATED));
1490
+ this.initialMount();
1491
+ }
1492
+ disconnectedCallback() {
1493
+ this.hasConnected = false;
1494
+ elementInstanceMap.delete(this);
1495
+ this.handleUnmount(this.getDisposeResult('destory'));
1496
+ if (elementInstanceMap.size === 0) {
1497
+ releasePatches();
1498
+ }
1499
+ }
1500
+ attributeChangedCallback(attr, _oldVal, newVal) {
1501
+ if (this.legalAttribute(attr, newVal) &&
1502
+ this[attr === ObservedAttrName.NAME ? 'appName' : 'appUrl'] !== newVal) {
1503
+ if (attr === ObservedAttrName.URL && !this.appUrl) {
1504
+ newVal = formatURL(newVal);
1505
+ if (!newVal) {
1506
+ return logError('Invalid attribute url');
1340
1507
  }
1341
- else {
1342
- this.handleCreate();
1508
+ this.appUrl = newVal;
1509
+ this.handleInitialNameAndUrl();
1510
+ }
1511
+ else if (attr === ObservedAttrName.NAME && !this.appName) {
1512
+ if (this.cacheData) {
1513
+ microApp.setData(newVal, this.cacheData);
1514
+ this.cacheData = null;
1343
1515
  }
1516
+ this.appName = newVal;
1517
+ this.handleInitialNameAndUrl();
1518
+ }
1519
+ else if (!this.isWating) {
1520
+ this.isWating = true;
1521
+ defer(this.handleAttributeUpdate);
1344
1522
  }
1345
1523
  }
1346
- else if (attrName !== this.appName) {
1347
- this.setAttribute('name', this.appName);
1348
- }
1349
- };
1350
- // cloned node of umd container also trigger constructor, we should skip
1351
- if (!this.querySelector('micro-app-head')) {
1352
- this.performWhenFirstCreated();
1353
- }
1354
- }
1355
- static get observedAttributes() {
1356
- return ['name', 'url'];
1357
- }
1358
- // 👇 Configuration
1359
- // shadowDom: use shadowDOM, default is false
1360
- // destory: whether delete cache resources when unmount, default is false
1361
- // inline: whether js runs in inline script mode, default is false
1362
- // disableScopecss: whether disable css scoped, default is false
1363
- // disableSandbox: whether disable sandbox, default is false
1364
- // macro: used to solve the async render problem of vue3, default is false
1365
- // baseRoute: route prefix, default is ''
1366
- connectedCallback() {
1367
- if (!elementInstanceMap.has(this)) {
1368
- this.performWhenFirstCreated();
1369
- }
1370
- defer(() => dispatchLifecyclesEvent(this, this.appName, lifeCycles.CREATED));
1371
- if (!this.appName || !this.appUrl)
1372
- return;
1373
- if (this.getDisposeResult('shadowDOM') && !this.shadowRoot) {
1374
- this.attachShadow({ mode: 'open' });
1375
1524
  }
1376
- const app = appInstanceMap.get(this.appName);
1377
- if (app) {
1378
- if (app.url === this.appUrl && (app.isPrefetch ||
1379
- app.getAppStatus() === appStatus.UNMOUNT)) {
1380
- this.handleAppMount(app);
1381
- }
1382
- else if (app.isPrefetch) {
1383
- logError(`the url: ${this.appUrl} is different from prefetch url: ${app.url}`);
1384
- }
1385
- else {
1386
- logError(`an app named ${this.appName} already exists`);
1525
+ // handle for connectedCallback run before attributeChangedCallback
1526
+ handleInitialNameAndUrl() {
1527
+ if (this.hasConnected) {
1528
+ this.initialMount();
1387
1529
  }
1388
1530
  }
1389
- else {
1390
- this.handleCreate();
1391
- }
1392
- }
1393
- disconnectedCallback() {
1394
- elementInstanceMap.delete(this);
1395
- this.handleUnmount(this.getDisposeResult('destory'));
1396
- if (elementInstanceMap.size === 0) {
1397
- releasePatches();
1398
- replaseUnmountAppInline();
1531
+ // Perform global initialization when the element count is 1
1532
+ performWhenFirstCreated() {
1533
+ if (elementInstanceMap.set(this, true).size === 1) {
1534
+ patchElementPrototypeMethods();
1535
+ rejectMicroAppStyle();
1536
+ replaseUnmountOfNestedApp();
1537
+ listenUmountOfNestedApp();
1538
+ }
1399
1539
  }
1400
- }
1401
- attributeChangedCallback(attr, _oldVal, newVal) {
1402
- if (this.legalAttribute(attr, newVal) &&
1403
- this[attr === ObservedAttrName.NAME ? 'appName' : 'appUrl'] !== newVal) {
1404
- if (attr === ObservedAttrName.URL && !this.appUrl) {
1405
- newVal = formatURL(newVal);
1406
- if (!newVal) {
1407
- return logError('Invalid attribute url');
1540
+ /**
1541
+ * first mount of this app
1542
+ */
1543
+ initialMount() {
1544
+ if (!this.appName || !this.appUrl)
1545
+ return;
1546
+ if (this.getDisposeResult('shadowDOM') && !this.shadowRoot) {
1547
+ this.attachShadow({ mode: 'open' });
1548
+ }
1549
+ const app = appInstanceMap.get(this.appName);
1550
+ if (app) {
1551
+ if (app.url === this.appUrl && (app.isPrefetch ||
1552
+ app.getAppStatus() === appStatus.UNMOUNT)) {
1553
+ this.handleAppMount(app);
1408
1554
  }
1409
- this.appUrl = newVal;
1410
- }
1411
- else if (attr === ObservedAttrName.NAME && !this.appName) {
1412
- if (this.cacheData) {
1413
- microApp.setData(newVal, this.cacheData);
1414
- this.cacheData = null;
1555
+ else if (app.isPrefetch) {
1556
+ logError(`the url: ${this.appUrl} is different from prefetch url: ${app.url}`);
1557
+ }
1558
+ else {
1559
+ logError(`an app named ${this.appName} already exists`);
1415
1560
  }
1416
- this.appName = newVal;
1417
1561
  }
1418
- else if (!this.isWating) {
1419
- this.isWating = true;
1420
- defer(this.handleAttributeUpdate);
1562
+ else {
1563
+ this.handleCreate();
1421
1564
  }
1422
1565
  }
1423
- }
1424
- // Perform global initialization when the element count is 1
1425
- performWhenFirstCreated() {
1426
- if (elementInstanceMap.set(this, true).size === 1) {
1427
- patchElementPrototypeMethods();
1428
- rejectMicroAppStyle();
1429
- listenUmountAppInline();
1566
+ /**
1567
+ * judge the attribute is legal
1568
+ * @param name attribute name
1569
+ * @param val attribute value
1570
+ */
1571
+ legalAttribute(name, val) {
1572
+ if (typeof val !== 'string' || !val) {
1573
+ logError(`unexpected attribute ${name}, please check again`);
1574
+ return false;
1575
+ }
1576
+ return true;
1430
1577
  }
1431
- }
1432
- /**
1433
- * judge the attribute is legal
1434
- * @param name attribute name
1435
- * @param val attribute value
1436
- */
1437
- legalAttribute(name, val) {
1438
- if (typeof val !== 'string' || !val) {
1439
- logError(`unexpected attribute ${name}, please check again`);
1440
- return false;
1578
+ /**
1579
+ * mount app
1580
+ * some serious note before mount:
1581
+ * 1. is prefetch ?
1582
+ * 2. is remount in another container ?
1583
+ * 3. is remount with change properties of the container ?
1584
+ */
1585
+ handleAppMount(app) {
1586
+ app.isPrefetch = false;
1587
+ defer(() => {
1588
+ var _a;
1589
+ return app.mount((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this, this.getDisposeResult('inline'), this.getBaseRouteCompatible());
1590
+ });
1441
1591
  }
1442
- return true;
1443
- }
1444
- /**
1445
- * mount app
1446
- * some serious note before mount:
1447
- * 1. is prefetch ?
1448
- * 2. is remount in another container ?
1449
- * 3. is remount with change properties of the container ?
1450
- */
1451
- handleAppMount(app) {
1452
- app.isPrefetch = false;
1453
- defer(() => {
1592
+ // create app instance
1593
+ handleCreate() {
1454
1594
  var _a;
1455
- return app.mount((_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this, this.getDisposeResult('inline'), this.getBaseRouteCompatible());
1456
- });
1457
- }
1458
- // create app instance
1459
- handleCreate() {
1460
- var _a;
1461
- const instance = new CreateApp({
1462
- name: this.appName,
1463
- url: this.appUrl,
1464
- container: (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this,
1465
- inline: this.getDisposeResult('inline'),
1466
- scopecss: !(this.getDisposeResult('disableScopecss') || this.getDisposeResult('shadowDOM')),
1467
- useSandbox: !this.getDisposeResult('disableSandbox'),
1468
- macro: this.getDisposeResult('macro'),
1469
- baseroute: this.getBaseRouteCompatible(),
1470
- });
1471
- appInstanceMap.set(this.appName, instance);
1472
- }
1473
- /**
1474
- * unmount app
1475
- * @param destory delete cache resources when unmount
1476
- */
1477
- handleUnmount(destory) {
1478
- const app = appInstanceMap.get(this.appName);
1479
- if (app && appStatus.UNMOUNT !== app.getAppStatus())
1480
- app.unmount(destory);
1481
- }
1482
- /**
1483
- * Get configuration
1484
- * Global setting is lowest priority
1485
- * @param name Configuration item name
1486
- */
1487
- getDisposeResult(name) {
1488
- // @ts-ignore
1489
- return (this.hasAttribute(name) || microApp[name]) && this.getAttribute(name) !== 'false';
1490
- }
1491
- /**
1492
- * 2021-09-08
1493
- * get baseRoute
1494
- * getAttribute('baseurl') is compatible writing of versions below 0.3.1
1495
- */
1496
- getBaseRouteCompatible() {
1497
- var _a, _b;
1498
- return (_b = (_a = this.getAttribute('baseroute')) !== null && _a !== void 0 ? _a : this.getAttribute('baseurl')) !== null && _b !== void 0 ? _b : '';
1499
- }
1500
- /**
1501
- * Data from the base application
1502
- */
1503
- set data(value) {
1504
- if (this.appName) {
1505
- microApp.setData(this.appName, value);
1595
+ const instance = new CreateApp({
1596
+ name: this.appName,
1597
+ url: this.appUrl,
1598
+ container: (_a = this.shadowRoot) !== null && _a !== void 0 ? _a : this,
1599
+ inline: this.getDisposeResult('inline'),
1600
+ scopecss: !(this.getDisposeResult('disableScopecss') || this.getDisposeResult('shadowDOM')),
1601
+ useSandbox: !this.getDisposeResult('disableSandbox'),
1602
+ macro: this.getDisposeResult('macro'),
1603
+ baseroute: this.getBaseRouteCompatible(),
1604
+ });
1605
+ appInstanceMap.set(this.appName, instance);
1506
1606
  }
1507
- else {
1508
- this.cacheData = value;
1607
+ /**
1608
+ * unmount app
1609
+ * @param destory delete cache resources when unmount
1610
+ */
1611
+ handleUnmount(destory) {
1612
+ const app = appInstanceMap.get(this.appName);
1613
+ if (app && appStatus.UNMOUNT !== app.getAppStatus())
1614
+ app.unmount(destory);
1509
1615
  }
1510
- }
1511
- /**
1512
- * get data only used in jsx-custom-event once
1513
- */
1514
- get data() {
1515
- if (this.appName) {
1516
- return microApp.getData(this.appName, true);
1616
+ /**
1617
+ * Get configuration
1618
+ * Global setting is lowest priority
1619
+ * @param name Configuration item name
1620
+ */
1621
+ getDisposeResult(name) {
1622
+ // @ts-ignore
1623
+ return (this.hasAttribute(name) || microApp[name]) && this.getAttribute(name) !== 'false';
1517
1624
  }
1518
- else if (this.cacheData) {
1519
- return this.cacheData;
1625
+ /**
1626
+ * 2021-09-08
1627
+ * get baseRoute
1628
+ * getAttribute('baseurl') is compatible writing of versions below 0.3.1
1629
+ */
1630
+ getBaseRouteCompatible() {
1631
+ var _a, _b;
1632
+ return (_b = (_a = this.getAttribute('baseroute')) !== null && _a !== void 0 ? _a : this.getAttribute('baseurl')) !== null && _b !== void 0 ? _b : '';
1633
+ }
1634
+ /**
1635
+ * Data from the base application
1636
+ */
1637
+ set data(value) {
1638
+ if (this.appName) {
1639
+ microApp.setData(this.appName, value);
1640
+ }
1641
+ else {
1642
+ this.cacheData = value;
1643
+ }
1644
+ }
1645
+ /**
1646
+ * get data only used in jsx-custom-event once
1647
+ */
1648
+ get data() {
1649
+ if (this.appName) {
1650
+ return microApp.getData(this.appName, true);
1651
+ }
1652
+ else if (this.cacheData) {
1653
+ return this.cacheData;
1654
+ }
1655
+ return null;
1520
1656
  }
1521
- return null;
1522
- }
1523
- }
1524
- /**
1525
- * define element
1526
- * @param tagName element name
1527
- */
1528
- function defineElement(tagName) {
1529
- if (window.customElements.get(tagName)) {
1530
- logWarn(`element ${tagName} is already defined`);
1531
- return false;
1532
1657
  }
1533
1658
  window.customElements.define(tagName, MicroAppElement);
1534
- return true;
1535
1659
  }
1536
1660
 
1537
1661
  class EventCenter {
@@ -1823,8 +1947,8 @@ class MicroApp extends EventCenterForBaseApp {
1823
1947
  this.preFetch = preFetch;
1824
1948
  }
1825
1949
  start(options) {
1826
- if (!(window === null || window === void 0 ? void 0 : window.customElements)) {
1827
- return logError('customElements is not supported in this environment');
1950
+ if (!isBrowser || !window.customElements) {
1951
+ return logError('micro-app is not supported in this environment');
1828
1952
  }
1829
1953
  if (options === null || options === void 0 ? void 0 : options.tagName) {
1830
1954
  if (/^micro-app(-\S+)?/.test(options.tagName)) {
@@ -1834,6 +1958,10 @@ class MicroApp extends EventCenterForBaseApp {
1834
1958
  return logError(`${options.tagName} is invalid tagName`);
1835
1959
  }
1836
1960
  }
1961
+ if (window.customElements.get(this.tagName)) {
1962
+ return logWarn(`element ${this.tagName} is already defined`);
1963
+ }
1964
+ initGloalEnv();
1837
1965
  if (options && toString.call(options) === '[object Object]') {
1838
1966
  this.shadowDOM = options.shadowDOM;
1839
1967
  this.destory = options.destory;
@@ -1903,7 +2031,7 @@ function flatChildren(parent, app, microAppHead) {
1903
2031
  if (dom.hasAttribute('exclude')) {
1904
2032
  parent.replaceChild(document.createComment('link element with exclude attribute ignored by micro-app'), dom);
1905
2033
  }
1906
- else if (app.scopecss) {
2034
+ else if (app.scopecss && !dom.hasAttribute('ignore')) {
1907
2035
  extractLinkFromHtml(dom, parent, app, microAppHead);
1908
2036
  }
1909
2037
  else if (dom.hasAttribute('href')) {
@@ -1914,7 +2042,7 @@ function flatChildren(parent, app, microAppHead) {
1914
2042
  if (dom.hasAttribute('exclude')) {
1915
2043
  parent.replaceChild(document.createComment('style element with exclude attribute ignored by micro-app'), dom);
1916
2044
  }
1917
- else if (app.scopecss) {
2045
+ else if (app.scopecss && !dom.hasAttribute('ignore')) {
1918
2046
  microAppHead.appendChild(scopedCSS(dom, app.name));
1919
2047
  }
1920
2048
  }
@@ -2032,15 +2160,6 @@ function bindFunctionToRawWidow(rawWindow, value) {
2032
2160
  return value;
2033
2161
  }
2034
2162
 
2035
- // save raw methods
2036
- const rawWindowAddEventListener = window.addEventListener;
2037
- const rawWindowRemoveEventListener = window.removeEventListener;
2038
- const rawSetInterval = window.setInterval;
2039
- const rawSetTimeout = window.setTimeout;
2040
- const rawClearInterval = window.clearInterval;
2041
- const rawClearTimeout = window.clearTimeout;
2042
- const rawDocumentAddEventListener = document.addEventListener;
2043
- const rawDocumentRemoveEventListener = document.removeEventListener;
2044
2163
  // document.onclick binding list, the binding function of each application is unique
2045
2164
  const documentClickListMap = new Map();
2046
2165
  let hasRewriteDocumentOnClick = false;
@@ -2078,7 +2197,7 @@ function overwriteDocumentOnClick() {
2078
2197
  }
2079
2198
  if (!hasDocumentClickInited && typeof f === 'function') {
2080
2199
  hasDocumentClickInited = true;
2081
- rawDocumentAddEventListener.call(document, 'click', onClickHandler, false);
2200
+ globalEnv.rawDocumentAddEventListener.call(globalEnv.rawDocument, 'click', onClickHandler, false);
2082
2201
  }
2083
2202
  }
2084
2203
  });
@@ -2091,6 +2210,7 @@ function overwriteDocumentOnClick() {
2091
2210
  */
2092
2211
  const documentEventListenerMap = new Map();
2093
2212
  function effectDocumentEvent() {
2213
+ const { rawDocument, rawDocumentAddEventListener, rawDocumentRemoveEventListener, } = globalEnv;
2094
2214
  if (!hasRewriteDocumentOnClick) {
2095
2215
  overwriteDocumentOnClick();
2096
2216
  }
@@ -2112,7 +2232,7 @@ function effectDocumentEvent() {
2112
2232
  }
2113
2233
  listener && (listener.__MICRO_MARK_OPTIONS__ = options);
2114
2234
  }
2115
- rawDocumentAddEventListener.call(document, type, listener, options);
2235
+ rawDocumentAddEventListener.call(rawDocument, type, listener, options);
2116
2236
  };
2117
2237
  document.removeEventListener = function (type, listener, options) {
2118
2238
  const appName = getCurrentAppName();
@@ -2125,13 +2245,13 @@ function effectDocumentEvent() {
2125
2245
  }
2126
2246
  }
2127
2247
  }
2128
- rawDocumentRemoveEventListener.call(document, type, listener, options);
2248
+ rawDocumentRemoveEventListener.call(rawDocument, type, listener, options);
2129
2249
  };
2130
2250
  }
2131
2251
  // Clear the document event agent
2132
2252
  function releaseEffectDocumentEvent() {
2133
- document.addEventListener = rawDocumentAddEventListener;
2134
- document.removeEventListener = rawDocumentRemoveEventListener;
2253
+ document.addEventListener = globalEnv.rawDocumentAddEventListener;
2254
+ document.removeEventListener = globalEnv.rawDocumentRemoveEventListener;
2135
2255
  }
2136
2256
  /**
2137
2257
  * Format event name
@@ -2153,6 +2273,7 @@ function effect(microWindow) {
2153
2273
  const eventListenerMap = new Map();
2154
2274
  const intervalIdMap = new Map();
2155
2275
  const timeoutIdMap = new Map();
2276
+ const { rawWindow, rawDocument, rawWindowAddEventListener, rawWindowRemoveEventListener, rawSetInterval, rawSetTimeout, rawClearInterval, rawClearTimeout, rawDocumentRemoveEventListener, } = globalEnv;
2156
2277
  // listener may be null, e.g test-passive
2157
2278
  microWindow.addEventListener = function (type, listener, options) {
2158
2279
  type = formatEventType(type, microWindow);
@@ -2164,7 +2285,7 @@ function effect(microWindow) {
2164
2285
  eventListenerMap.set(type, new Set([listener]));
2165
2286
  }
2166
2287
  listener && (listener.__MICRO_MARK_OPTIONS__ = options);
2167
- rawWindowAddEventListener.call(window, type, listener, options);
2288
+ rawWindowAddEventListener.call(rawWindow, type, listener, options);
2168
2289
  };
2169
2290
  microWindow.removeEventListener = function (type, listener, options) {
2170
2291
  type = formatEventType(type, microWindow);
@@ -2172,25 +2293,25 @@ function effect(microWindow) {
2172
2293
  if ((listenerList === null || listenerList === void 0 ? void 0 : listenerList.size) && listenerList.has(listener)) {
2173
2294
  listenerList.delete(listener);
2174
2295
  }
2175
- rawWindowRemoveEventListener.call(window, type, listener, options);
2296
+ rawWindowRemoveEventListener.call(rawWindow, type, listener, options);
2176
2297
  };
2177
2298
  microWindow.setInterval = function (handler, timeout, ...args) {
2178
- const intervalId = rawSetInterval(handler, timeout, ...args);
2299
+ const intervalId = rawSetInterval.call(rawWindow, handler, timeout, ...args);
2179
2300
  intervalIdMap.set(intervalId, { handler, timeout, args });
2180
2301
  return intervalId;
2181
2302
  };
2182
2303
  microWindow.setTimeout = function (handler, timeout, ...args) {
2183
- const timeoutId = rawSetTimeout(handler, timeout, ...args);
2304
+ const timeoutId = rawSetTimeout.call(rawWindow, handler, timeout, ...args);
2184
2305
  timeoutIdMap.set(timeoutId, { handler, timeout, args });
2185
2306
  return timeoutId;
2186
2307
  };
2187
2308
  microWindow.clearInterval = function (intervalId) {
2188
2309
  intervalIdMap.delete(intervalId);
2189
- rawClearInterval(intervalId);
2310
+ rawClearInterval.call(rawWindow, intervalId);
2190
2311
  };
2191
2312
  microWindow.clearTimeout = function (timeoutId) {
2192
2313
  timeoutIdMap.delete(timeoutId);
2193
- rawClearTimeout(timeoutId);
2314
+ rawClearTimeout.call(rawWindow, timeoutId);
2194
2315
  };
2195
2316
  const umdWindowListenerMap = new Map();
2196
2317
  const umdDocumentListenerMap = new Map();
@@ -2256,7 +2377,7 @@ function effect(microWindow) {
2256
2377
  if (eventListenerMap.size) {
2257
2378
  eventListenerMap.forEach((listenerList, type) => {
2258
2379
  for (const listener of listenerList) {
2259
- rawWindowRemoveEventListener.call(window, type, listener);
2380
+ rawWindowRemoveEventListener.call(rawWindow, type, listener);
2260
2381
  }
2261
2382
  });
2262
2383
  eventListenerMap.clear();
@@ -2264,13 +2385,13 @@ function effect(microWindow) {
2264
2385
  // Clear timers
2265
2386
  if (intervalIdMap.size) {
2266
2387
  intervalIdMap.forEach((_, intervalId) => {
2267
- rawClearInterval(intervalId);
2388
+ rawClearInterval.call(rawWindow, intervalId);
2268
2389
  });
2269
2390
  intervalIdMap.clear();
2270
2391
  }
2271
2392
  if (timeoutIdMap.size) {
2272
2393
  timeoutIdMap.forEach((_, timeoutId) => {
2273
- rawClearTimeout(timeoutId);
2394
+ rawClearTimeout.call(rawWindow, timeoutId);
2274
2395
  });
2275
2396
  timeoutIdMap.clear();
2276
2397
  }
@@ -2281,7 +2402,7 @@ function effect(microWindow) {
2281
2402
  if (documentAppListenersMap) {
2282
2403
  documentAppListenersMap.forEach((listenerList, type) => {
2283
2404
  for (const listener of listenerList) {
2284
- rawDocumentRemoveEventListener.call(document, type, listener);
2405
+ rawDocumentRemoveEventListener.call(rawDocument, type, listener);
2285
2406
  }
2286
2407
  });
2287
2408
  documentAppListenersMap.clear();
@@ -2335,6 +2456,8 @@ class SandBox {
2335
2456
  this.microWindow = {}; // Proxy target
2336
2457
  this.injectedKeys = new Set(); // Properties newly added to microWindow
2337
2458
  this.escapeKeys = new Set(); // Properties escape to rawWindow, cleared when unmount
2459
+ const rawWindow = globalEnv.rawWindow;
2460
+ const rawDocument = globalEnv.rawDocument;
2338
2461
  const descriptorTargetMap = new Map();
2339
2462
  const hasOwnProperty = (key) => this.microWindow.hasOwnProperty(key) || rawWindow.hasOwnProperty(key);
2340
2463
  // get scopeProperties and escapeProperties from plugins
@@ -2370,10 +2493,11 @@ class SandBox {
2370
2493
  return eval;
2371
2494
  }
2372
2495
  }
2373
- if (this.scopeProperties.includes(key)) {
2496
+ if (Reflect.has(target, key)) {
2374
2497
  return Reflect.get(target, key);
2375
2498
  }
2376
- if (Reflect.has(target, key)) {
2499
+ if (this.scopeProperties.includes(key) ||
2500
+ (typeof key === 'string' && /^__MICRO_APP_/.test(key))) {
2377
2501
  return Reflect.get(target, key);
2378
2502
  }
2379
2503
  const rawValue = Reflect.get(rawWindow, key);
@@ -2457,8 +2581,8 @@ class SandBox {
2457
2581
  if (!this.active) {
2458
2582
  this.active = true;
2459
2583
  this.microWindow.__MICRO_APP_BASE_ROUTE__ = this.microWindow.__MICRO_APP_BASE_URL__ = baseroute;
2460
- if (rawWindow._babelPolyfill)
2461
- rawWindow._babelPolyfill = false;
2584
+ if (globalEnv.rawWindow._babelPolyfill)
2585
+ globalEnv.rawWindow._babelPolyfill = false;
2462
2586
  if (++SandBox.activeCount === 1) {
2463
2587
  effectDocumentEvent();
2464
2588
  }
@@ -2475,7 +2599,7 @@ class SandBox {
2475
2599
  });
2476
2600
  this.injectedKeys.clear();
2477
2601
  this.escapeKeys.forEach((key) => {
2478
- Reflect.deleteProperty(rawWindow, key);
2602
+ Reflect.deleteProperty(globalEnv.rawWindow, key);
2479
2603
  });
2480
2604
  this.escapeKeys.clear();
2481
2605
  if (--SandBox.activeCount === 0) {
@@ -2485,6 +2609,7 @@ class SandBox {
2485
2609
  }
2486
2610
  // record umd snapshot before the first execution of umdHookMount
2487
2611
  recordUmdSnapshot() {
2612
+ this.microWindow.__MICRO_APP_UMD_MODE__ = true;
2488
2613
  this.recordUmdEffect();
2489
2614
  recordDataCenterSnapshot(this.microWindow.microApp);
2490
2615
  this.recordUmdinjectedValues = new Map();
@@ -2544,8 +2669,8 @@ class SandBox {
2544
2669
  microWindow.__MICRO_APP_NAME__ = appName;
2545
2670
  microWindow.__MICRO_APP_PUBLIC_PATH__ = getEffectivePath(url);
2546
2671
  microWindow.microApp = new EventCenterForMicroApp(appName);
2547
- microWindow.rawWindow = rawWindow;
2548
- microWindow.rawDocument = rawDocument;
2672
+ microWindow.rawWindow = globalEnv.rawWindow;
2673
+ microWindow.rawDocument = globalEnv.rawDocument;
2549
2674
  microWindow.removeDomScope = removeDomScope;
2550
2675
  }
2551
2676
  }
@@ -2617,7 +2742,7 @@ class CreateApp {
2617
2742
  * @param baseroute route prefix, default is ''
2618
2743
  */
2619
2744
  mount(container, inline, baseroute) {
2620
- var _a, _b, _c, _d;
2745
+ var _a, _b, _c;
2621
2746
  if (typeof inline === 'boolean' && inline !== this.inline) {
2622
2747
  this.inline = inline;
2623
2748
  }
@@ -2632,23 +2757,27 @@ class CreateApp {
2632
2757
  cloneNode(this.source.html, this.container);
2633
2758
  (_b = this.sandBox) === null || _b === void 0 ? void 0 : _b.start(this.baseroute);
2634
2759
  if (!this.umdHookMount) {
2635
- execScripts(this.source.scripts, this);
2636
- const { mount, unmount } = this.getUmdLibraryHooks();
2637
- // if mount & unmount is function, the sub app is umd mode
2638
- if (isFunction(mount) && isFunction(unmount)) {
2639
- this.umdHookMount = mount;
2640
- this.umdHookunMount = unmount;
2641
- (_c = this.sandBox) === null || _c === void 0 ? void 0 : _c.recordUmdSnapshot();
2642
- /**
2643
- * TODO: Some UI frameworks insert and record container elements to micro-app-body, such as modal and notification. The DOM remounted is a cloned element, so the cached elements of UI frameworks are invalid, this may cause bug when remount app
2644
- */
2645
- cloneNode(this.container, this.source.html);
2646
- formatHTMLStyleAfterUmdInit(this.source.html, this.name);
2647
- this.umdHookMount();
2648
- }
2760
+ execScripts(this.source.scripts, this, () => {
2761
+ var _a;
2762
+ if (this.umdHookMount === null) {
2763
+ const { mount, unmount } = this.getUmdLibraryHooks();
2764
+ // if mount & unmount is function, the sub app is umd mode
2765
+ if (isFunction(mount) && isFunction(unmount)) {
2766
+ this.umdHookMount = mount;
2767
+ this.umdHookunMount = unmount;
2768
+ (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.recordUmdSnapshot();
2769
+ /**
2770
+ * TODO: Some UI frameworks insert and record container elements to micro-app-body, such as modal and notification. The DOM remounted is a cloned element, so the cached elements of UI frameworks are invalid, this may cause bug when remount app
2771
+ */
2772
+ cloneNode(this.container, this.source.html);
2773
+ formatHTMLStyleAfterUmdInit(this.source.html, this.name);
2774
+ this.umdHookMount();
2775
+ }
2776
+ }
2777
+ });
2649
2778
  }
2650
2779
  else {
2651
- (_d = this.sandBox) === null || _d === void 0 ? void 0 : _d.rebuildUmdSnapshot();
2780
+ (_c = this.sandBox) === null || _c === void 0 ? void 0 : _c.rebuildUmdSnapshot();
2652
2781
  this.umdHookMount();
2653
2782
  }
2654
2783
  if (appStatus.UNMOUNT !== this.status) {
@@ -2697,7 +2826,7 @@ class CreateApp {
2697
2826
  var _a, _b;
2698
2827
  // after execScripts, the app maybe unmounted
2699
2828
  if (appStatus.UNMOUNT !== this.status) {
2700
- const global = ((_b = (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow) !== null && _b !== void 0 ? _b : rawWindow);
2829
+ const global = ((_b = (_a = this.sandBox) === null || _a === void 0 ? void 0 : _a.proxyWindow) !== null && _b !== void 0 ? _b : globalEnv.rawWindow);
2701
2830
  const libraryName = (this.container instanceof ShadowRoot ? this.container.host : this.container).getAttribute('library') || `micro-app-${this.name}`;
2702
2831
  return typeof global[libraryName] === 'object' ? global[libraryName] : {};
2703
2832
  }
@@ -2737,6 +2866,9 @@ function filterPreFetchTarget(apps) {
2737
2866
  * @param apps micro apps
2738
2867
  */
2739
2868
  function preFetch(apps) {
2869
+ if (!isBrowser) {
2870
+ return logError('preFetch is only supported in browser environment');
2871
+ }
2740
2872
  requestIdleCallback(() => {
2741
2873
  if (typeof apps === 'function')
2742
2874
  apps = apps();
@@ -2798,5 +2930,5 @@ function getGlobalAssets(assets) {
2798
2930
  }
2799
2931
 
2800
2932
  export default microApp;
2801
- export { preFetch, pureCreateElement, removeDomScope, version };
2933
+ export { preFetch, pureCreateElement, removeDomScope, setCurrentAppName, version };
2802
2934
  //# sourceMappingURL=index.esm.js.map