低代码引擎资产包协议规范

186 阅读11分钟

# 《低代码引擎资产包协议规范》

# 1 介绍

# 1.1 本协议规范涉及的问题域

  • 定义本协议版本号规范
  • 定义本协议中每个子规范需要被支持的 Level
  • 定义本协议相关的领域名词
  • 定义低代码资产包协议版本号规范(A)
  • 定义低代码资产包协议组件及依赖资源描述规范(A)
  • 定义低代码资产包协议组件描述资源加载规范(A)
  • 定义低代码资产包协议组件在面板展示规范(AA)

# 1.2 协议草案起草人

  • 撰写:金禅、璿玑、彼洋
  • 审阅:力皓、絮黎、光弘、戊子、潕量、游鹿

# 1.3 版本号

1.1.0

# 1.4 协议版本号规范(A)

本协议采用语义版本号,版本号格式为 major.minor.patch 的形式。

  • major 是大版本号:用于发布不向下兼容的协议格式修改
  • minor 是小版本号:用于发布向下兼容的协议功能新增
  • patch 是补丁号:用于发布向下兼容的协议问题修正

# 1.5 协议中子规范 Level 定义

规范等级实现要求
A基础规范,低代码引擎核心层支持;
AA推荐规范,由低代码引擎官方插件、setter 支持。
AAA参考规范,需由基于引擎的上层搭建平台支持,实现可参考该规范。

# 1.6 名词术语

  • 资产包: 低代码引擎加载资源的动态数据集合,主要包含组件及其依赖的资源、组件低代码描述、动态插件/设置器资源等。

# 1.7 背景

根据低代码引擎的实现,一个组件要在引擎上渲染和配置,需要提供组件的 umd 资源以及组件的低代码描述,并且组件通常都是以集合的形式被引擎消费的;除了组件之外,还有组件的依赖资源、引擎的动态插件/设置器等资源也需要注册到引擎中;因此我们定义了“低代码资产包”这个数据结构,来描述引擎所需加载的动态资源的集合。

# 1.8 受众

本协议适用于使用“低代码引擎”构建搭建平台的开发者,通过本协议的定义来进行资源的分类和加载。阅读及使用本协议,需要对低代码搭建平台的交互和实现有一定的了解,对前端开发相关技术栈的熟悉也会有帮助,协议中对通用的前端相关术语不会做进一步的解释说明。

# 2 协议结构

协议最顶层结构如下,包含 7 方面的描述内容:

  • version { String } 当前协议版本号
  • packages { Array } 低代码编辑器中加载的资源列表
  • components { Array } 所有组件的描述协议列表
  • sort { Object } 用于描述组件面板中的 tab 和 category
  • plugins { Array } 设计器插件描述协议列表
  • setters { Array } 设计器中设置器描述协议列表
  • extConfig { Object } 平台自定义扩展字段

# 2.1 version(A)

定义当前协议 schema 的版本号;

根属性名称类型说明变量支持默认值
versionString协议版本号-1.1.0

# 2.2 packages(A)

定义低代码编辑器中加载的资源列表,包含公共库和组件(库) cdn 资源等;

字段字段描述字段类型规范等级备注
packages[].id?资源唯一标识StringA资源唯一标识,如果为空,则以 package 为唯一标识
packages[].title?资源标题StringA资源标题
packages[].packagenpm 包名StringA组件资源唯一标识
packages[].versionnpm 包版本号StringA组件资源版本号
packages[].type资源包类型StringAA取值为: proCode(源码)、lowCode(低代码,默认为 proCode
packages[].schema低代码组件 schema 内容objectAA取值为: proCode(源码)、lowCode(低代码)
packages[].deps当前资源包的依赖资源的唯一标识列表ArrayA唯一标识为 id 或者 package 对应的值
packages[].library作为全局变量引用时的名称,用来定义全局变量名StringA低代码引擎通过该字段获取组件实例
packages[].editUrls组件编辑态视图打包后的 CDN url 列表,包含 js 和 cssArrayA低代码引擎编辑器会加载这些 url
packages[].urls组件渲染态视图打包后的 CDN url 列表,包含 js 和 cssArrayAA低代码引擎渲染模块会加载这些 url
packages[].advancedEditUrls组件多个编辑态视图打包后的 CDN url 列表集合,包含 js 和 cssObjectAAA上层平台根据特定标识提取某个编辑态的资源,低代码引擎编辑器会加载这些资源,优先级高于 packages[].editUrls
packages[].advancedUrls组件多个端的渲染态视图打包后的 CDN url 列表集合,包含 js 和 cssObjectAAA上层平台根据特定标识提取某个渲染态的资源, 低代码引擎渲染模块会加载这些资源,优先级高于 packages[].urls
packages[].external当前资源在作为其他资源的依赖,在其他依赖打包时时是否被排除了(同 webpack 中 external 概念)BooleanAAA某些资源会被单独提取出来,是其他依赖的前置依赖,根据这个字段决定是否提前加载该资源
packages[].loadEnv指定当前资源加载的环境ArrayAAA主要用于指定 external 资源加载的环境,取值为 design(设计态)、runtime(预览态)中的一个或多个
packages[].exportSourceId标识当前 package 内容是从哪个 package 导出来的StringAAA此时 urls 无效
packages[].exportSourceLibrary标识当前 package 是从 window 上的哪个属性导出来的StringAAAexportSourceId 的优先级高于exportSourceLibrary ,此时 urls 无效
packages[].async标识当前 package 资源加载在 window.library 上的是否是一个异步对象BooleanAasync 为 true 时,需要通过 await 才能拿到真正内容
packages[].exportMode标识当前 package 从其他 package 的导出方式StringA目前只支持 "functionCall", exportMode等于 "functionCall" 时,当前package 的内容以函数的方式从其他 package 中导出,具体导出接口如: (library: string, packageName: string, isRuntime?: boolean) => any

描述举例:

{
  "packages": [
    {
      "title": "fusion 组件库",
      "package": "@alifd/next",
      "version": "1.23.0",
      "urls": [
        "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next.min.css",
        "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next-with-locales.min.js"
      ],
      "library": "Next"
    },
    {
      "title": "Fusion 精品组件库",
      "package": "@alife/fusion-ui",
      "version": "0.1.5",
      "editUrls": [
        "https://g.alicdn.com/code/npm/@alife/fusion-ui/0.1.7/build/lowcode/view.js",
        "https://g.alicdn.com/code/npm/@alife/fusion-ui/0.1.7/build/lowcode/view.css"
      ],
      "urls": [
        "https://g.alicdn.com/code/npm/@alife/fusion-ui/0.1.7/dist/FusionUI.js",
        "https://g.alicdn.com/code/npm/@alife/fusion-ui/0.1.7/dist/FusionUI.css"
      ],
      "library": "FusionUI"
    },
    {
      "title": "低代码组件 A",
      "id": "lcc-a",
      "version": "0.1.5",
      "type": "lowCode",
      "schema": {
        "componentsMap": [
          {
            "package": "@ali/vc-text",
            "componentName": "Text",
            "version": "4.1.1"
          }
        ],
        "utils": [
          {
            "name": "dataSource",
            "type": "npm",
            "content": {
              "package": "@ali/vu-dataSource",
              "exportName": "dataSource",
              "version": "1.0.4"
            }
          }
        ],
        "componentsTree": [
          {
            "defaultProps": {
              "content": "这是默认值"
            },
            "methods": {
              "__initMethods__": {
                "compiled": "function (exports, module) { /*set actions code here*/ }",
                "source": "function (exports, module) { /*set actions code here*/ }",
                "type": "js"
              }
            },
            "loopArgs": ["item", "index"],
            "props": {
              "mobileSlot": {
                "type": "JSBlock",
                "value": {
                  "children": [
                    {
                      "condition": true,
                      "hidden": false,
                      "isLocked": false,
                      "conditionGroup": "",
                      "componentName": "Text",
                      "id": "node_ockxiczf4m2",
                      "title": "",
                      "props": {
                        "maxLine": 0,
                        "showTitle": false,
                        "behavior": "NORMAL",
                        "content": {
                          "en-US": "Title",
                          "zh-CN": "页面标题",
                          "type": "i18n"
                        },
                        "__style__": {},
                        "fieldId": "text_kxiczgj4"
                      }
                    }
                  ],
                  "componentName": "Slot",
                  "props": {
                    "slotName": "mobileSlot",
                    "slotTitle": "mobile 容器"
                  }
                }
              },
              "className": "component_k8e4naln",
              "useDevice": false,
              "fieldId": "symbol_k8bnubw4"
            },
            "condition": true,
            "children": [
              {
                "condition": true,
                "loopArgs": [null, null],
                "componentName": "Text",
                "id": "node_ockxiczf4m4",
                "props": {
                  "maxLine": 0,
                  "showTitle": false,
                  "behavior": "NORMAL",
                  "content": {
                    "variable": "props.content",
                    "type": "variable",
                    "value": {
                      "use": "zh-CN",
                      "en-US": "Tips content",
                      "zh-CN": "这是一个低代码组件",
                      "type": "i18n"
                    }
                  },
                  "fieldId": "text_kxid1d9n"
                }
              }
            ],
            "propTypes": [
              {
                "defaultValue": "这是默认值",
                "name": "content",
                "title": "文本内容",
                "type": "string"
              }
            ],
            "componentName": "Component",
            "id": "node_k8bnubvz",
            "state": {}
          }
        ]
      },
      "library": "LCCA"
    },
    {
      "title": "多端组件库",
      "package": "@ali/atest1",
      "version": "1.23.0",
      "advancedUrls": {
        "default": [
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css",
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/main.3354663.js"
        ],
        "mobile": [
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css",
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/main.mobile.3354663.js"
        ],
        "rax": [
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css",
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/main.rax.3354663.js"
        ]
      },
      "advancedEditUrls": {
        "design": [
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css",
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/editView.design.js"
        ],
        "default": [
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css",
          "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/editView.js"
        ]
      },
      "library": "Atest1"
    },
    {
      "library":"UiPaaSServerless3",
      "advancedUrls":{
          "default":[
              "https://g.alicdn.com/legao-comp/serverless3/1.1.0/env-staging-d224466e-0614-497d-8cd5-e4036dc50b70/main.js"
          ]
      },
      "id":"UiPaaSServerless3-view",
      "type":"procode",
      "version":"1.0.0"
    },
    {
      "package":"react-color",
      "library":"ReactColor",
      "id":"react-color",
      "type":"procode",
      "version":"2.19.3",
      "async":true,
      "exportMode":"functionCall",
      "exportSourceId":"UiPaaSServerless3-view"
    }
  ]
}

# 2.3 components (A)

定义资产包中包含的所有组件的低代码描述的集合,分为“ComponentDescription”和“RemoteComponentDescription”(详见 2.6 TypeScript 定义):

  • ComponentDescription: 符合“组件描述协议”的数据,详见物料规范中2.2.2 组件描述协议部分;
  • RemoteComponentDescription 是将一个或多个 ComponentDescription 构建打包的 js 资源的描述,在浏览器中加载该资源后可获取到其中包含的每个组件的 ComponentDescription 的具体内容;

# 2.4 sort (AA)

定义组件列表分组

根属性名称类型说明变量支持默认值
sort.groupListString[]组件分组,用于组件面板 tab 展示-['精选组件', '原子组件']
sort.categoryListString[]组件面板中同一个 tab 下的不同区间用 category 区分,category 的排序依照 categoryList 顺序排列-['通用', '数据展示', '表格类', '表单类']

# 2.5 plugins (AAA)

自定义设计器插件列表

根属性名称类型说明变量支持默认值
plugins[].nameString插件名称--
plugins[].titleString插件标题--
plugins[].descriptionString插件描述--
plugins[].docUrlString插件文档地址--
plugins[].screenshotString插件截图地址--
plugins[].tagsString[]插件标签分类--
plugins[].keywordsString[]插件检索关键字--
plugins[].referenceReference插件引用的资源包信息--

# 2.6 setters (AAA)

自定义设置器列表

根属性名称类型说明变量支持默认值
setters[].nameString设置器组件名称--
setters[].titleString设置器标题--
setters[].descriptionString设置器描述--
setters[].docUrlString设置器文档地址--
setters[].screenshotString设置器截图地址--
setters[].tagsString[]设置器标签分类--
setters[].keywordsString[]设置器检索关键字--
setters[].referenceReference设置器引用的资源包信息--

# 2.7 extConfig (AAA)

定义平台相关的扩展内容,用于存放平台自身实现的一些私有协议, 以允许存量平台能够平滑地迁移至标准协议。 extConfig 是一个 key-value 结构的对象,协议不会规定 extConfig 中的字段名称以及类型, 完全自定义

# 2.8 TypeScript 定义

组件低代码描述相关部分字段含义详见物料规范中2.2.2 组件描述协议部分;


/**
 * 资产包协议
 */
export interface Assets {
  /**
   * 资产包协议版本号
   */
  version: string;
  /**
   * 资源列表
   */
  packages?: Array<Package>;
  /**
   * 所有组件的描述协议集合
   */
  components: Array<ComponentDescription|RemoteComponentDescription>;
  /**
   * 低代码编辑器插件集合
   */
  plugins?: Array<PluginDescription>;
  /**
   * 低代码设置器集合
   */
  setters?: Array<SetterDescription>;
  /**
   * 平台扩展配置
   */
  extConfig?: AssetsExtConfig;
  /**
   * 用于描述组件面板中的 tab 和 category
   */
  sort: ComponentSort;
}

export interface AssetsExtConfig{
  [index: string]: any;
}

/**
 * 描述组件面板中的 tab 和 category 排布
 */
export interface ComponentSort {
  /**
   * 用于描述组件面板的 tab 项及其排序,例如:["精选组件", "原子组件"]
   */
  groupList?: String[];
  /**
   * 组件面板中同一个 tab 下的不同区间用 category 区分,category 的排序依照 categoryList 顺序排列;
   */
  categoryList?: String[];
}

/**
 * 定义资产包依赖信息
 */
export interface Package {
  /**
   * 唯一标识
   */
  id: string;
  /**
   * 包名
   */
  package: string;
  /**
   * 包版本号
   */
  version: string;
  /**
   * 资源类型
   */
  type: string;
  /**
   * 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css
   */
  urls?: string[] | any;
  /**
   * 组件多个渲染态视图打包后的 CDN url 列表,包含 js 和 css,优先级高于 urls
   */
  advancedUrls?: ComplexUrls;
  /**
   * 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css
   */
  editUrls?: string[] | any;
  /**
   * 组件多个编辑态视图打包后的 CDN url 列表,包含 js 和 css,优先级高于 editUrls
   */
  advancedEditUrls?: ComplexUrls;
  /**
   * 低代码组件的 schema 内容
   */
  schema?: ComponentSchema;
  /**
   * 当前资源所依赖的其他资源包的 id 列表
   */
  deps?: string[];
  /**
   * 指定当前资源加载的环境
   */
  loadEnv?: LoadEnv[];
  /**
   * 当前资源是否是 external 资源
   */
  external?: boolean;
  /**
   * 作为全局变量引用时的名称,和 webpack output.library 字段含义一样,用来定义全局变量名
   */
  library: string;
  /**
   * 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容;
   */
  exportName?: string;
  /**
   * 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 
   */
  async?: boolean;
  /**
   * 标识当前 package 从其他 package 的导出方式
   */
  exportMode?: string;
  /**
   * 标识当前 package 内容是从哪个 package 导出来的 
   */
  exportSourceId?: string;
  /**
   * 标识当前 package 是从 window 上的哪个属性导出来的 
   */
  exportSourceLibrary?: string;
}


/**
 * 复杂 urls 结构,同时兼容简单结构和多模态结构
 */
export type ComplexUrls = string[] | MultiModeUrls;

/**
 * 多模态资源
 */
export interface MultiModeUrls {
  /**
   * 默认的资源 url
   */
  default: string[];
  /**
   * 其他模态资源的 url
   */
  [index: string]: string[];
}


/**
 * 资源加载环境种类
 */
export enum LoadEnv {
  /**
   * 设计态
   */
	design = "design",
  /**
   * 运行态
   */
  runtime = "runtime"
}

/**
 * 低代码设置器描述
 */
export type SetterDescription = PluginDescription;

/**
 * 低代码插件器描述
 */
export interface PluginDescription {
  /**
   * 插件名称
   */
  name: string;
  /**
   * 插件标题
   */
  title: string;
  /**
   * 插件类型
   */
  type?: string;
  /**
   * 插件描述
   */
  description?: string;
  /**
   * 插件文档地址
   */
  docUrl: string;
  /**
   * 插件截图
   */
  screenshot: string;
  /**
   * 插件相关的标签
   */
  tags?: string[];
  /**
   * 插件关键字
   */
  keywords?: string[];
  /**
   * 插件引用的资源信息
   */
  reference: Reference;
}

/**
 * 资源引用信息,Npm 的升级版本,
 */
export interface Reference {
  /**
   * 引用资源的 id 标识
   */
  id?: string;
  /**
   * 引用资源的包名
   */
  package?: string;
  /**
   * 引用资源的导出对象中的属性值名称
   */
  exportName: string;
  /**
   * 引用 exportName 上的子对象
   */
  subName: string;
  /**
   * 引用的资源主入口
   */
  main?: string;
  /**
   * 是否从引用资源的导出对象中获取属性值
   */
  destructuring: boolean;
  /**
   * 资源版本号
   */
  version: string;
}


/**
 * 低代码片段
 *
 * 内容为组件不同状态下的低代码 schema (可以有多个),用户从组件面板拖入组件到设计器时会向页面 schema 中插入 snippets 中定义的组件低代码 schema
 */
export interface Snippet {
  title: string;
  screenshot?: string;
  schema: ElementJSON;
}

/**
 * 组件低代码描述
 */
export interface ComponentDescription {
  componentName: string;
  title: string;
  description?: string;
  docUrl: string;
  screenshot: string;
  icon?: string;
  tags?: string[];
  keywords?: string[];
  devMode?: 'proCode' | 'lowCode';
  npm: Npm;
  props: Prop[];
  configure: Configure;
  /**
   * 多模态下的组件描述, 优先级高于 configure
   */
  advancedConfigures: MultiModeConfigures;
  snippets: Snippet[];
  group: string;
  category: string;
  priority: number;
  /**
   * 组件引用的资源信息
   */
  reference: Reference;
}

export interface MultiModeConfigures {
  default: Configure;
  [index: string]: Configure;
}

/**
 * 远程物料描述
 */
export interface RemoteComponentDescription {
  /**
   * 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容;
   */
  exportName?: string;
  /**
   * 组件描述的资源链接;
   */
  url?: string;
  /**
   * 组件多模态描述的资源信息,优先级高于 url
   */
  advancedUrls?: ComplexUrl;
  /**
   * 组件(库)的 npm 信息;
   */
  package?: {
    npm?: string;
  };
}

export type ComplexUrl = string | MultiModeUrl

export interface MultiModeUrl {
  default: string;
  [index: string]: string;
}

export interface ComponentSchema {
  version: string;
  componentsMap: ComponentsMap;
  componentsTree: [ComponentTree];
  i18n: I18nMap;
  utils: UtilItem[];
}