Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wujie 子应用中动态插入script 脚本,加载的代码出现依赖报错问题 #465

Closed
fychinesepjj opened this issue Mar 23, 2023 · 4 comments

Comments

@fychinesepjj
Copy link

逻辑描述
子应用会动态加载多个 script urls,Promise.all 等待所有资源 onload , 继续执行后续代码。

bug描述

  1. 正常情况下,当子应用独立运行时,代码执行流程: 加载script脚本 -> 解析执行 -> onload,无报错情况
  2. 异常情况下,当子应用是在wujie的iframe运行时,wujie时通过fetch加载script(非jsIgnores情况),执行流程变成: fetch script 脚本 -> onload -> 执行

错误情况与wujie代码逻辑iframe.js中的insertScriptToIframe有关系。
它改变了script脚本必须同步串行之行的逻辑导致报错。

通过增加 plugins jsIgnores 配置,同样也会出现报错情况

    <WujieVue
      width="100%"
      height="100%"
      name="A"
      url="http://172.21.113.223:8000/demo.html"
      :plugins="[{ 'jsIgnores': [/.*\.js/] }]"
      >
      </WujieVue>

现象截图

正常情况

子应用是独立页面打开运行,代码无报错情况
image

错误情况

子应用是被wujie加载运行,代码出现依赖报错情况
image

主要代码

主应用

页面代码

<template>
  <div class="hello">
    <WujieVue
      width="100%"
      height="100%"
      name="A"
      url="http://172.21.113.223:8000/demo.html"
      >
      </WujieVue>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {};
  }
}
</script>

子应用

js代码

function createDefer() {
  const r = {};
  const promise = new Promise((resolve, reject) => {
    r.resolve = resolve;
    r.reject = reject;
  });

  r.promise = () => promise;

  return r;
}

function load(src) {
  const element = document.createElement('script');
  element.onload = onload;
  element.onerror = onload;

  const i = createDefer();
  function onload(e) {
    element.onload = null;
    element.onerror = null;
    if (e.type === 'load') {
      i.resolve();
    } else {
      i.reject();
    }
  }

  element.src = src
  element.async = false;
  document.head.appendChild(element);
  return i.promise();
}

function loadUrls(urls = []) {
  return Promise.all(urls.map(url => load(url)))
}


loadUrls([
  'https://g.alicdn.com/code/lib/react/16.13.1/umd/react.development.js',
  'https://g.alicdn.com/code/lib/react-dom/16.13.1/umd/react-dom.development.js',
  'http://g.alicdn.com/code/lib/antd/4.19.4/antd.min.js',
  'http://at.alicdn.com/t/font_2369445_ukrtsovd92r.js',
  'http://g.alicdn.com/code/npm/@ali/ant-design-icons-cdn/4.5.0/index.umd.min.js',
  'https://alifd.alicdn.com/npm/@alilc/[email protected]/build/lowcode/view.js'
]).then(() => {
  console.log('load assets done')
})

html 代码

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
  </head>
  <body>
    <h1>测试子应用</h1>
    <script src="./demo.js"></script>
  </body>
</html>
@yiludege
Copy link
Collaborator

yiludege commented Mar 24, 2023

昨晚发了版本,试试新版本有没有这个问题呢


已经定位到问题,主要是head.appendChild这个过程会进行外联转内联的过程,这个过程没有按照顺序来插入内联后的代码

@fychinesepjj
Copy link
Author

fychinesepjj commented Mar 24, 2023

当主应用只有一个子应用时运行正常,但同时配置两个子应用依然会报错
image

<template>
  <div class="hello">
    <WujieVue
      width="40%"
      height="100%"
      name="A"
      url="http://172.21.113.223:8000/demo.html"
      >
      </WujieVue>
    <WujieVue
      width="40%"
      height="100%"
      name="C"
      url="http://172.21.113.223:8000/demo.html"
      >
      </WujieVue>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {};
  }
}
</script>

@yiludege
Copy link
Collaborator

我这边两个同时放不会有报错的情况,如果是100%复现的话,可以传一下代码吗

@fychinesepjj
Copy link
Author

我这边两个同时放不会有报错的情况,如果是100%复现的话,可以传一下代码吗

我重新删除node_modules,更新到1.0.11 ,目前没出现问题了,感谢~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants