lowcode-engine icon indicating copy to clipboard operation
lowcode-engine copied to clipboard

feat(designer): modify the load order of the simulator

Open keuby opened this issue 3 years ago • 15 comments

修改 simulator 加载顺序,将其放在资源加载之前。

原因

在加载画布本身的同时,可能还需要加载一些框架运行时,比如 vue 的运行时,而一些资源加载的时候(比如 vue 组件库),是需依赖于 vue 运行时的,故而将 simulator 加载提前

keuby avatar Jul 27 '22 06:07 keuby

可以提供一些具体的例子来说明一下嘛?

liujuping avatar Jul 27 '22 06:07 liujuping

可以提供一些具体的例子来说明一下嘛?

例如我们的 assets.json 里面引入了 vue 组件库 naive-ui https://unpkg.com/[email protected]/dist/index.js

{
  "packages": [
    {
      "package": "naive-ui",
      "version": "2.31.0",
      "urls": ["https://unpkg.com/[email protected]/dist/index.prod.js"],
      "library": "naive"
    }
  ],
  "components": [
    // ...
  ]
}

然后在设计器的初始化的时候需要加载适配器的 url

await init(document.getElementById("lce-container"), {
  simulatorUrl: [
    "https://unpkg.com/@knxcloud/lowcode-vue-simulator-renderer/dist/vue-simulator-renderer.js",
    "https://unpkg.com/@knxcloud/lowcode-vue-simulator-renderer/dist/vue-simulator-renderer.css",
  ],
});

此时,他们都需要依赖于 vue 的运行时资源,比如:https://unpkg.com/[email protected]/dist/vue.runtime.global.js,这个资源的加载需要再适配器和组件库资源加载之前

keuby avatar Jul 27 '22 10:07 keuby

在修改了加载顺序之后,那么在加载适配器资源的时候,就可以顺便把 vue 运行时加上

await init(document.getElementById("lce-container"), {
  simulatorUrl: [
    "https://unpkg.com/[email protected]/dist/vue.runtime.global.js",
    "https://unpkg.com/@knxcloud/lowcode-vue-simulator-renderer/dist/vue-simulator-renderer.js",
    "https://unpkg.com/@knxcloud/lowcode-vue-simulator-renderer/dist/vue-simulator-renderer.css",
  ],
});

keuby avatar Jul 27 '22 10:07 keuby

没看懂,为什么simulator之后还有文件要加载?simulator运行时理论上所有资源都加载完毕了

LeoYuan avatar Jul 27 '22 11:07 LeoYuan

没看懂,为什么simulator之后还有文件要加载?simulator运行时理论上所有资源都加载完毕了

重点其实不在这里,我们需要有一个合适的时机去加载 vue 的运行时。在 react 版本中,react 的运行时是在 设计器里面加载的,simulator 中,是通过 environment,直接从设计器的 window 中直接赋值到了 simulator 所在的 iframe 的 window 上

但是这样做的话,所有 dom 元素,其实都是基于外层设计器的 Element 元素创建的。当在 simulator 的 iframe 中,如果存在 el instanceof Element 这种代码的话。他的判定永远都会是 false,会造成很多不可预期的 bug

keuby avatar Jul 27 '22 11:07 keuby

按照我的理解,其实 react 应该也存在一样的问题吧 🐶

keuby avatar Jul 27 '22 11:07 keuby

没看懂,为什么simulator之后还有文件要加载?simulator运行时理论上所有资源都加载完毕了

重点其实不在这里,我们需要有一个合适的时机去加载 vue 的运行时。在 react 版本中,react 的运行时是在 设计器里面加载的,simulator 中,是通过 environment,直接从设计器的 window 中直接赋值到了 simulator 所在的 iframe 的 window 上

但是这样做的话,所有 dom 元素,其实都是基于外层设计器的 Element 元素创建的。当在 simulator 的 iframe 中,如果存在 el instanceof Element 这种代码的话。他的判定永远都会是 false,会造成很多不可预期的 bug

vue 的运行时(我理解类似 react-dom?)放到 library 中靠前的位置会有问题么?

LeoYuan avatar Jul 27 '22 11:07 LeoYuan

vue 的运行时(我理解类似 react-dom?)放到 library 中靠前的位置会有问题么?

你的意思是说放到 assets.json 的 packages 字段里面么?像这样?

{
  "packages": [
    {
      "package": "vue",
      "version": "3.2.37",
      "urls": ["https://unpkg.com/[email protected]/dist/vue.runtime.global.js"],
      "library": "Vue"
    },
    {
      "package": "naive-ui",
      "version": "2.30.6",
      "urls": ["https://unpkg.com/[email protected]/dist/index.prod.js"],
      "library": "naive"
    }
  ],
}

这样子操作的话,从实现上来看是没啥问题的,但是其实不太合适,这样子做会存在很多其他的问题。

  1. 资源加载的时候,对于物料资源的 assets.json 里面其实不应该存在 vue 本身的运行时,因为他需要再各个物料之间共享
  2. packages 里面的 library 存在 vue 运行时的话,在导出 schema 时候会将 vue 运行时保存进去,在预览的时候,加载资源就肯呢个会重复加载 vue 运行时

当然上述都可以通过一些代码逻辑判断来解决,但是我觉得这些东西应该可以在框架层面通过一些配置来避免

keuby avatar Jul 27 '22 11:07 keuby

library 的意思就是加载包啊,不管是 react / react-dom,还是 moment / lodash,还是 custom-comps,语意上没有问题~

LeoYuan avatar Jul 27 '22 11:07 LeoYuan

library 的意思就是加载包啊,不管是 react / react-dom,还是 moment / lodash,还是 custom-comps,语意上没有问题~

是的,但是这边的 library 其实应该算是动态加载的包,比如 moment / lodash 这种,他是属于可有也可以没有的那种包

而对于一个 vue 的设计器来说,vue 运行时不应该属于动态加载,可有可没有的,而是必定会加载,而且需要再非常靠前的位置加载的,虽然都是加载包,我觉得还是有本质区别的

keuby avatar Jul 27 '22 12:07 keuby

而且我觉得 simulator 放在靠前的位置加载也更加合理,因为动态加载的 library 可能依赖 simulator,但是 simulator 不会,也不应该依赖其他动态加载 的 library

举个例子,比如我存在另外一个 simulator 动态加载的扩展包,可以对 simulator 做一些功能上的补充和扩展,比如扩充他的渲染器类型,比如对他对定制化的配置等

keuby avatar Jul 27 '22 12:07 keuby

simulator 的定位就是最后一步渲染了,资源都已经加载完毕,什么场景会其他 lib 来依赖 simulator?

你可以看看 react-simulator-renderer 的实现~

LeoYuan avatar Jul 27 '22 12:07 LeoYuan

simulator 的定位就是最后一步渲染了,资源都已经加载完毕,什么场景会其他 lib 来依赖 simulator?

你可以看看 react-simulator-renderer 的实现~

嗯嗯,我理解你的意思,simulator 确实应该最后加载。但是对于像 Vue 运行时这种,对于 vue 低代码设计器必定会加载的这种资源,或许需要有一个地方来设置他在所有动态加载的 library 之前加载,而不应该被配置在 assets 里面

keuby avatar Jul 27 '22 12:07 keuby

加没问题,但是要有案例说明为什么要加?你目前这个例子不太有说服力。。。

LeoYuan avatar Jul 27 '22 13:07 LeoYuan

This PR is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 2 days.

github-actions[bot] avatar Aug 07 '22 02:08 github-actions[bot]

这个 PR 我这边先关掉了,如果后面有需要可以再补充一下案例再打开/创建一个新的。

liujuping avatar Aug 16 '22 02:08 liujuping