@blueking/bk-weweb 0.0.2-5.beta.1 → 0.0.2-5.beta.2

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.
@@ -37,6 +37,7 @@ var AppState;
37
37
  AppState["UNSET"] = "UNSET";
38
38
  })(AppState || (AppState = {}));
39
39
 
40
+ // 当前正在运行的app
40
41
  let currentRunningApp = null;
41
42
  function getCurrentRunningApp() {
42
43
  return currentRunningApp;
@@ -325,6 +326,7 @@ function loadInstance(props) {
325
326
  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
326
327
  * IN THE SOFTWARE.
327
328
  */
329
+ // unmount
328
330
  function unmount(appKey) {
329
331
  const app = appCache.getApp(appKey);
330
332
  if (app && app.status !== AppState.UNMOUNT) {
@@ -360,6 +362,7 @@ function unmount(appKey) {
360
362
  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
361
363
  * IN THE SOFTWARE.
362
364
  */
365
+ // deactivated
363
366
  function deactivated(appKey) {
364
367
  const app = appCache.getApp(appKey);
365
368
  if (app && [AppState.ACTIVATED, AppState.MOUNTED].includes(app.status)) {
@@ -576,6 +579,11 @@ class Style {
576
579
  this.fromHtml = fromHtml;
577
580
  this.initial = initial ?? false;
578
581
  }
582
+ /**
583
+ * @param templateStyle 模板样式
584
+ * @param styleElement 样式node
585
+ * @param app 应用实例
586
+ */
579
587
  commonScoped(templateStyle, styleElement, app) {
580
588
  if (app.scopeCss && !(app.container instanceof ShadowRoot)) {
581
589
  const rules = Array.from(templateStyle.sheet?.cssRules ?? []);
@@ -612,6 +620,10 @@ class Style {
612
620
  delete styleElement.__BK_WEWEB_APP_KEY__;
613
621
  return styleElement;
614
622
  }
623
+ /**
624
+ * @param app 应用实例
625
+ * @returns 返回执行后的style标签
626
+ */
615
627
  async excuteCode(app) {
616
628
  app.registerRunningApp();
617
629
  let styleElement = this.createStyleElement();
@@ -828,21 +840,22 @@ async function excuteAppStyles(app, container) {
828
840
  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
829
841
  * IN THE SOFTWARE.
830
842
  */
843
+ // bk-kweweb 微模块模式
831
844
  class MicroInstanceModel {
832
- state = AppState.UNSET;
833
- appCacheKey;
834
- container;
835
- data;
836
- initSource;
837
- isPreLoad = false;
838
- keepAlive;
839
- name;
840
- sandBox;
841
- scopeCss = true;
842
- scopeJs = false;
843
- showSourceCode = true;
844
- source;
845
- url;
845
+ state = AppState.UNSET; // 当前实例状态
846
+ appCacheKey; // 缓存key
847
+ container; // 容器
848
+ data; // 数据
849
+ initSource; // 初始资源
850
+ isPreLoad = false; // 是否预加载
851
+ keepAlive; // 是否缓存
852
+ name; // 名称
853
+ sandBox; // 沙箱
854
+ scopeCss = true; // 是否隔离样式
855
+ scopeJs = false; // 是否隔离js
856
+ showSourceCode = true; // 是否显示源码
857
+ source; // 入口资源
858
+ url; // url
846
859
  constructor(props) {
847
860
  this.name = props.id !== props.url ? props.id : random(5);
848
861
  this.appCacheKey = props.id || this.name;
@@ -924,12 +937,6 @@ class MicroInstanceModel {
924
937
  await this.source.importEntery(this);
925
938
  }
926
939
  }
927
- set status(v) {
928
- this.state = v;
929
- }
930
- get status() {
931
- return this.state;
932
- }
933
940
  unmount(needDestroy) {
934
941
  this.state = AppState.UNMOUNT;
935
942
  this.sandBox?.deactivated();
@@ -937,6 +944,12 @@ class MicroInstanceModel {
937
944
  this.container.innerHTML = '';
938
945
  this.container = undefined;
939
946
  }
947
+ set status(v) {
948
+ this.state = v;
949
+ }
950
+ get status() {
951
+ return this.state;
952
+ }
940
953
  }
941
954
 
942
955
  /*
@@ -991,6 +1004,11 @@ class Script {
991
1004
  this.fromHtml = fromHtml ?? false;
992
1005
  this.initial = initial ?? false;
993
1006
  }
1007
+ /**
1008
+ * @param app 应用
1009
+ * @param needRelaceScriptElement 是否需要替换script标签
1010
+ * @returns 返回执行后的script标签或注释
1011
+ */
994
1012
  async excuteCode(app, needRelaceScriptElement = false) {
995
1013
  try {
996
1014
  if (!this.code)
@@ -1036,6 +1054,7 @@ class Script {
1036
1054
  }
1037
1055
  return;
1038
1056
  }
1057
+ // 内存脚本执行
1039
1058
  executeMemoryScript(app, scopedCode) {
1040
1059
  try {
1041
1060
  const isScopedLocation = app instanceof MicroAppModel && app.scopeLocation;
@@ -1047,6 +1066,7 @@ class Script {
1047
1066
  console.error(e);
1048
1067
  }
1049
1068
  }
1069
+ // 脚本标签执行
1050
1070
  executeSourceScript(scriptElement, scopedCode) {
1051
1071
  if (this.isModule) {
1052
1072
  if (this.url?.match(/\.ts$/)) {
@@ -1063,6 +1083,7 @@ class Script {
1063
1083
  }
1064
1084
  this.url && scriptElement.setAttribute('origin-src', this.url);
1065
1085
  }
1086
+ // 获取脚本内容
1066
1087
  async getCode(app) {
1067
1088
  if (this.code.length || !this.url) {
1068
1089
  return this.code;
@@ -1086,6 +1107,7 @@ class Script {
1086
1107
  setCode(code) {
1087
1108
  this.code = code;
1088
1109
  }
1110
+ // 转换脚本内容
1089
1111
  transformCode(app) {
1090
1112
  if (app.sandBox) {
1091
1113
  if (app.showSourceCode || this.isModule) {
@@ -1166,8 +1188,13 @@ async function execAppScripts(app) {
1166
1188
  }
1167
1189
  const appScriptList = Array.from(app.source.scripts.values()).filter(script => script.fromHtml && !script.initial);
1168
1190
  const commomList = appScriptList.filter(script => (!script.async && !script.defer) || script.isModule);
1191
+ let i = 0;
1192
+ while (i < commomList.length && commomList[i]) {
1193
+ await commomList[i].excuteCode(app);
1194
+ i++;
1195
+ }
1169
1196
  // 保证同步脚本 和 module类型 最先执行
1170
- await Promise.all(commomList.map(script => script.excuteCode(app)));
1197
+ // await Promise.all(commomList.map(script => script.excuteCode(app)));
1171
1198
  // 最后执行 defer 和 async 脚本
1172
1199
  const deferScriptList = [];
1173
1200
  const asyncScriptList = [];
@@ -1482,6 +1509,7 @@ function resetBodyAndHeaderMethods() {
1482
1509
  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1483
1510
  * IN THE SOFTWARE.
1484
1511
  */
1512
+ // before load
1485
1513
  function beforeLoad() {
1486
1514
  rewriteBodyAndHeaderMethods();
1487
1515
  }
@@ -1511,6 +1539,7 @@ function beforeLoad() {
1511
1539
  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1512
1540
  * IN THE SOFTWARE.
1513
1541
  */
1542
+ // 激活应用
1514
1543
  function activated(appKey, container, callback) {
1515
1544
  const app = appCache.getApp(appKey);
1516
1545
  if (app?.status === AppState.DEACTIVATED && app.keepAlive) {
@@ -2313,23 +2342,24 @@ class SandBox {
2313
2342
  * IN THE SOFTWARE.
2314
2343
  */
2315
2344
  const BLANK_ORIGN = 'about:blank';
2345
+ // bk-weweb 微应用模式
2316
2346
  class MicroAppModel {
2317
- state = AppState.UNSET;
2318
- container;
2319
- data;
2320
- iframe = null;
2321
- initSource;
2322
- isPreLoad = false;
2323
- keepAlive;
2347
+ state = AppState.UNSET; // 状态
2348
+ container; // 容器
2349
+ data; // 数据
2350
+ iframe = null; // scoped iframe
2351
+ initSource; // 初始资源
2352
+ isPreLoad = false; // 是否预加载
2353
+ keepAlive; // 是否缓存
2324
2354
  mode = WewebMode.APP;
2325
- name;
2326
- sandBox;
2327
- scopeCss;
2328
- scopeJs;
2329
- scopeLocation;
2330
- showSourceCode;
2331
- source;
2332
- url;
2355
+ name; // 名称
2356
+ sandBox; // 沙箱
2357
+ scopeCss; // 是否隔离样式
2358
+ scopeJs; // 是否隔离js
2359
+ scopeLocation; // 是否隔离location
2360
+ showSourceCode; // 是否显示源码
2361
+ source; // 入口资源
2362
+ url; // url
2333
2363
  constructor(props) {
2334
2364
  this.name = props.id !== props.url ? props.id : random(5);
2335
2365
  this.mode = props.mode ?? WewebMode.APP;
@@ -2350,6 +2380,7 @@ class MicroAppModel {
2350
2380
  this.container.setAttribute(CSS_ATTRIBUTE_KEY, this.name);
2351
2381
  }
2352
2382
  }
2383
+ // 激活
2353
2384
  activated(container, callback) {
2354
2385
  this.isPreLoad = false;
2355
2386
  this.state = AppState.ACTIVATED;
@@ -2367,6 +2398,7 @@ class MicroAppModel {
2367
2398
  callback?.(this);
2368
2399
  }
2369
2400
  }
2401
+ // 创建隔离iframe
2370
2402
  createIframe() {
2371
2403
  return new Promise(resolve => {
2372
2404
  const iframe = document.createElement('iframe');
@@ -2721,11 +2753,12 @@ class AppCache {
2721
2753
  constructor() {
2722
2754
  this.cache = new Map();
2723
2755
  this.baseSource = new EntrySource(location.href);
2724
- // this.baseApp = new
2725
2756
  }
2757
+ // 删除缓存
2726
2758
  deleteApp(url) {
2727
2759
  this.cache.delete(url);
2728
2760
  }
2761
+ // 获取缓存app
2729
2762
  getApp(name) {
2730
2763
  if (!name)
2731
2764
  return undefined;
@@ -2734,6 +2767,7 @@ class AppCache {
2734
2767
  return app;
2735
2768
  return Array.from(this.cache.values()).find((item) => item.name === name);
2736
2769
  }
2770
+ // 获取缓存app
2737
2771
  getBaseAppStyle(urlOrCode) {
2738
2772
  return this.baseSource.getStyle(urlOrCode);
2739
2773
  }
@@ -2812,6 +2846,12 @@ window.__getAppOrInstance__ = function (id) {
2812
2846
  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2813
2847
  * IN THE SOFTWARE.
2814
2848
  */
2849
+ /**
2850
+ * @param url 资源地址
2851
+ * @param style 样式实例
2852
+ * @param originLink 原始link标签
2853
+ * @returns 返回替换的style标签
2854
+ */
2815
2855
  function getStyleSource(url, style, originLink) {
2816
2856
  const replaceStyle = document.createElement('style');
2817
2857
  setMarkElement(replaceStyle);
@@ -2828,6 +2868,12 @@ function getStyleSource(url, style, originLink) {
2828
2868
  });
2829
2869
  return replaceStyle;
2830
2870
  }
2871
+ /**
2872
+ * @param url 资源地址
2873
+ * @param script 脚本实例
2874
+ * @param originScript 原始script标签
2875
+ * @returns 返回替换的script标签
2876
+ */
2831
2877
  function getScriptSource(url, script, originScript) {
2832
2878
  const replaceScript = document.createElement('script');
2833
2879
  setMarkElement(replaceScript);
@@ -2851,6 +2897,10 @@ function getScriptSource(url, script, originScript) {
2851
2897
  });
2852
2898
  return replaceScript;
2853
2899
  }
2900
+ /**
2901
+ * @param child link或者script标签
2902
+ * @returns 返回替换的link或者script标签
2903
+ */
2854
2904
  function createNewNode(child) {
2855
2905
  if (child instanceof HTMLLinkElement) {
2856
2906
  const rel = child.getAttribute('rel');
@@ -2885,9 +2935,20 @@ function createNewNode(child) {
2885
2935
  }
2886
2936
  return child;
2887
2937
  }
2938
+ /**
2939
+ * @param node 节点
2940
+ * @returns 返回是否是link或者script标签
2941
+ */
2888
2942
  function isLinkOrScript(node) {
2889
2943
  return node instanceof HTMLLinkElement || node instanceof HTMLScriptElement;
2890
2944
  }
2945
+ /**
2946
+ * @param parent 父节点
2947
+ * @param newChild 新节点
2948
+ * @param passiveChild 被动节点
2949
+ * @param rawMethod 原始方法
2950
+ * @returns 返回原始方法的执行结果
2951
+ */
2891
2952
  function baseElementInertHandle(parent, newChild, passiveChild, rawMethod) {
2892
2953
  if (isLinkOrScript(newChild)) {
2893
2954
  const targetChild = createNewNode(newChild);
@@ -2895,6 +2956,12 @@ function baseElementInertHandle(parent, newChild, passiveChild, rawMethod) {
2895
2956
  }
2896
2957
  return rawMethod.call(parent, newChild, passiveChild);
2897
2958
  }
2959
+ /**
2960
+ * @param parent 父节点
2961
+ * @param newChild 新节点
2962
+ * @param rawMethod 原始方法
2963
+ * @returns 返回原始方法的执行结果
2964
+ */
2898
2965
  function baseElementAppendHandle(parent, newChild, rawMethod) {
2899
2966
  if (isLinkOrScript(newChild)) {
2900
2967
  const targetChild = createNewNode(newChild);
@@ -2928,6 +2995,9 @@ function baseElementAppendHandle(parent, newChild, rawMethod) {
2928
2995
  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2929
2996
  * IN THE SOFTWARE.
2930
2997
  */
2998
+ /**
2999
+ * 收集主应用的资源
3000
+ */
2931
3001
  function collectBaseSource() {
2932
3002
  const rawBodyAppendChild = HTMLBodyElement.prototype.appendChild;
2933
3003
  const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;