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

动态加载自定义物料时,自动加载其附带的自定义setter

Open sy296565890 opened this issue 1 year ago • 56 comments

大佬好,请教下怎么在独立的一个物料工程里(类似 lowcode-materials) ,同时 【导出】自定义的setter 并使其伴随物料一起加载 不需要额外的setter加载代码,或者说大佬您推荐如何动态加载物料关联的自定义setter

尝试了一些方法

  1. 在物料库的index.tsx 文件中 使用如下代码
import * as React from "react";
import { ProFormDigit } from '@ant-design/pro-components';  // ProFormDigit 样式异常了

export default class CustomSetter extends React.PureComponent<any> {
  static displayName = 'CustomSetter ';

  render() { 
    return (
      <ProFormDigit />
    );
  }
}
const registerSetter = window.top.AliLowCodeEngine.setters.registerSetter
registerSetter('CustomSetter', CustomSetter)
  1. 注册官方setter后面加入
      //  注册官方的setterMap【低代码主应用】
      setters.registerSetter(setterMap);
      setters.registerSetter('CustomSetter', CustomSetter);
      // 虽然可以使用  但没办法做到不更新低代码主应用的时候  动态加入新的物料和setter
  1. 期望setter可以像动态加载 assets一样 或者有近似的办法

sy296565890 avatar Apr 18 '23 02:04 sy296565890

在自定义物料库尝试了 const registerSetter = window.top.AliLowCodeEngine.setters.registerSetter registerSetter('CustomSetter', CustomSetter) 虽然组件能加载出来但是css丢失了 使用了antd5【 cssinjs】 却依然没有样式

sy296565890 avatar Apr 18 '23 14:04 sy296565890

已经尝试了下面几种办法 操作方式1 【css缺失,且弹框控件被局限在模拟器里面】 const registerSetter = window.top.AliLowCodeEngine.setters.registerSetter registerSetter('CustomSetter', CustomSetter) 操作方式2 【正常可用 但低代码主应用不支持动态加载自定义setter】 setters.registerSetter(setterMap); // 挂在官方setters setters.registerSetter('CustomSetter', CustomSetter); // 正常使用 操作方式3 【无法使用antd组件库】 自定义物料库 src同级文件夹lowcode下加入_setter

sy296565890 avatar Apr 18 '23 14:04 sy296565890

力皓大佬建议: 我建议就是在 plugin 去注册,在外层注册,把 setter 跟物料写在一起不太优雅,耦合了

  1. setter 是在外层使用,组件是在渲染器使用,没必要一起加载,然后强行再让部分css内部iframe生效,部分外部生效(我估计你也不好分开,混一起了);
  2. simulator iframe的一大作用就是让渲染环境更纯碎,不被设计器相关的css影响,setter css强行混入干扰,算负向优化了;

sy296565890 avatar Apr 18 '23 14:04 sy296565890

1681802705172_A072975E-BF75-4a42-8075-97C4C77DF84E

sy296565890 avatar Apr 18 '23 14:04 sy296565890

这个时候的业务setter本身就是个强耦合组件同时跟函数服务进行了强关联 貌似不分开也是合理的 只是在强耦合的情况下 如何优雅的加载是个问题

sy296565890 avatar Apr 18 '23 14:04 sy296565890

力皓大佬的建议虽然能解决setter样式问题,但是低代码主应用不停机的情况下动态加载新增的自定义setter的问题依然存在,还望大佬们能指点一二

sy296565890 avatar Apr 18 '23 14:04 sy296565890

setter: CustomSetter,

如果是物料自定义的 setter,不是全局通用的,直接在使用到的物料配置 setter 的时候通过这种方法使用即可,没有必要再注册到全局。

如果必须要注册到全局,那就应该像是资产包一样,可以开发一个插件

1.找到这个资产包依赖的 setter, 2.请求 setter 的 js / css, 3.并使用 api 注入到全局。

不建议在物料代码里面再处理 setter。

liujuping avatar Apr 19 '23 03:04 liujuping

setter: CustomSetter, 没太明白这个在哪使用,方便给个示例吗

sy296565890 avatar Apr 19 '23 03:04 sy296565890

这块引擎上目前是没有处理的,你可以基于上面的思路扩展一下,主要还是将setter和物料分离,并且在适当的时候加载专属的setter,防止放全局影响资源

hzd822 avatar Apr 19 '23 03:04 hzd822

首先 上面所说的setter是业务setter,属于强耦合类型,不是全局通用的 物料配置是说的meta.ts文件吗? meta.js 引用不了src里面的组件

sy296565890 avatar Apr 19 '23 03:04 sy296565890

这块引擎上目前是没有处理的,你可以基于上面的思路扩展一下,主要还是将setter和物料分离,并且在适当的时候加载专属的setter,防止放全局影响资源 看了上面的解释 依然没法吧这个强耦合类型的setter进行分开 除非使用单仓多包 否则开发一个插件 要维护两套代码
但是单仓多包 开发一个插件依然是耦合的

sy296565890 avatar Apr 19 '23 03:04 sy296565890

现在的物料包也没有view.css了 强制导入view.js还不够 有点懵 image

sy296565890 avatar Apr 19 '23 03:04 sy296565890

meta.ts 为什么要引入 src 里面的文件?应该放到 lowcode 目录下呀。

liujuping avatar Apr 19 '23 06:04 liujuping

dev 模式没有 view.css ,build 的时候是有的

jinchanz avatar Apr 19 '23 06:04 jinchanz

@sy296565890

我理解你是想把 setter 列表放到资产包里,后面可以动态修改资产包里的 setter 数据,而不需要更新低代码应用的代码是吧;

我建议用资产包里的这个字段 AssetsExtConfig(这是扩展字段,你自己定义就行) ,把 setter 列表写在里面,然后在低代码主应用里获取这里的 setter 列表进行注册就行了。

jinchanz avatar Apr 19 '23 06:04 jinchanz

你说的方案3其实也行,就是把 setter 写到 lowcode 目录下,最后打包进 meta.js 里,但是你说不能用 antd ,但是应该是可以的,我没验证过。不过这个确实不是推荐做法,这会导致 meta.js 比较大并且可能影响低代码主应用的样式。

jinchanz avatar Apr 19 '23 06:04 jinchanz

由于antd v5 是cssinjs v4直接引入资源后可以通过【const { Button, InputNumber } = window.antd;】使用

sy296565890 avatar Apr 19 '23 06:04 sy296565890

v5也是可以使用的 但是有很多的问题,貌似不是最佳实践

import { createElement } from 'react';
import { ProFormDigit } from '@ant-design/pro-components';
import { InputNumber } from 'antd';
import { default as DigitalSignature } from './components/signature-digital'
window.okok = {
  ProFormDigit, // 可以使用
  InputNumber, // 可以使用
  DigitalSignature // 不能使用
}
// export { ProFormDigit } from '@ant-design/pro-components';
// //@ts-ignore
const registerSetter = window.top.AliLowCodeEngine.setters.registerSetter
// setTimeout(() => {
//   registerSetter('CustomSetter', CustomSetter)
// }, 0);

const NumberSetter2: React.FC<any> = () => {
  const { Button, InputNumber } = antd;
  // const {ProFormDigit} = ProComponents;
  const aa  = createElement(window.okok.ProFormDigit, {})
  const bb  = createElement(window.okok.DigitalSignature, {})
  return (
    <>
      <Button>ssssssss</Button>
      <InputNumber />
      {/* <ProFormDigit /> */}
      {aa}
      {bb}
    </>
  )
}

sy296565890 avatar Apr 19 '23 06:04 sy296565890

哦,明白了,在 lowcode 目录写组件确实可能遇到各种各样的问题,因为它设计出来只是为了写组件的配置描述信息的。

jinchanz avatar Apr 19 '23 06:04 jinchanz

v5也是可以使用的 但是有很多的问题,貌似不是最佳实践

import { createElement } from 'react';
import { ProFormDigit } from '@ant-design/pro-components';
import { InputNumber } from 'antd';
import { default as DigitalSignature } from './components/signature-digital'
window.okok = {
  ProFormDigit, // 可以使用
  InputNumber, // 可以使用
  DigitalSignature // 不能使用
}
// export { ProFormDigit } from '@ant-design/pro-components';
// //@ts-ignore
const registerSetter = window.top.AliLowCodeEngine.setters.registerSetter
// setTimeout(() => {
//   registerSetter('CustomSetter', CustomSetter)
// }, 0);

const NumberSetter2: React.FC<any> = () => {
  const { Button, InputNumber } = antd;
  // const {ProFormDigit} = ProComponents;
  const aa  = createElement(window.okok.ProFormDigit, {})
  const bb  = createElement(window.okok.DigitalSignature, {})
  return (
    <>
      <Button>ssssssss</Button>
      <InputNumber />
      {/* <ProFormDigit /> */}
      {aa}
      {bb}
    </>
  )
}

嗯,这样太 hack 了,如果带来的理解成本和研发成本大于把 setter 拆分出来,还是拆分出来的好,哈哈

jinchanz avatar Apr 19 '23 06:04 jinchanz

是的 这样写太怪异了,拆出来的话可以使用lerna或pnpm 一仓多包的方式共享自定义组件部分的代码,但是如何动态引入呢 或者说 仅仅引入链接 可以做到自动 registerSetter(setterMap)吗

sy296565890 avatar Apr 19 '23 06:04 sy296565890

@sy296565890

我理解你是想把 setter 列表放到资产包里,后面可以动态修改资产包里的 setter 数据,而不需要更新低代码应用的代码是吧;

我建议用资产包里的这个字段 AssetsExtConfig(这是扩展字段,你自己定义就行) ,把 setter 列表写在里面,然后在低代码主应用里获取这里的 setter 列表进行注册就行了。

AssetsExtConfig 这个方便写个使用示例吗, 我的理解 Assets 仅仅只是json对象, 还是说渲染之前需要自定义解析一下这一段?

sy296565890 avatar Apr 19 '23 06:04 sy296565890

image 看看这个回复,我没有具体想好,可以类似这样:

// assets.json

{
  packages: [],
 components: [],
  ......
  ......
  AssetsExtConfig: {
    // 类似官方 setter 打包好的资源
    setters: [
      //  'https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/css/engine-ext.css',
      // 'https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/js/engine-ext.js',
    ]
  }
  
}

低代码应用获取到资产包里的 AssetsExtConfig.setters ,然后动态把这里的资源加到 html 里就行了,你可以试试

jinchanz avatar Apr 19 '23 06:04 jinchanz

image 看看这个回复,我没有具体想好,可以类似这样:

// assets.json

{
  packages: [],
 components: [],
  ......
  ......
  AssetsExtConfig: {
    // 类似官方 setter 打包好的资源
    setters: [
      //  'https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/css/engine-ext.css',
      // 'https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/js/engine-ext.js',
    ]
  }
  
}

低代码应用获取到资产包里的 AssetsExtConfig.setters ,然后动态把这里的资源加到 html 里就行了,你可以试试

这个做法似乎是可行的,但是setter项目支持npm run dev吗,否则的话貌似不便于调试

sy296565890 avatar Apr 19 '23 06:04 sy296565890

setter 其实也就是组件,总有办法的,去试试吧,哈哈

jinchanz avatar Apr 19 '23 06:04 jinchanz

@jinchanz 大佬 这一部分 这样加载可行吗?

var link = window.top.document.createElement('link');
link.rel = "stylesheet";
link.href = 'https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/css/engine-ext.css';
window.top.document.head.appendChild(link);

var script = window.top.document.createElement('script');
script.src = 'https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/js/engine-ext.js';
window.top.document.head.appendChild(script);

sy296565890 avatar Apr 19 '23 07:04 sy296565890

// lowCodeExternals
"@alilc/lowcode-engine-ext": "AliLowCodeEngineExt",
// "@alilc/lowcode-engine-ext": "window.AliLowCodeEngineExt",
// 
import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext';

const { setterMap, pluginMap } = AliLowCodeEngineExt;
// const { setterMap, pluginMap } = window.AliLowCodeEngineExt;

// 注册setterMap
setters.registerSetter(setterMap);

感觉万变不离其宗,又回来了 哈哈

sy296565890 avatar Apr 19 '23 07:04 sy296565890

做个记录 image

sy296565890 avatar Apr 19 '23 07:04 sy296565890

@jinchanz 大佬 有时间了再帮忙看看呀~ 感谢~

sy296565890 avatar Apr 20 '23 07:04 sy296565890

@jinchanz 大佬 有时间了再帮忙看看呀~ 感谢~

怎么样、、你那边现在是怎么处理的

xiaochena avatar Apr 25 '23 09:04 xiaochena