From d3010f26b7515a094d90e3ed02394b6a0ca79bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=91=E7=A6=85?= Date: Thu, 22 Jul 2021 16:23:27 +0800 Subject: [PATCH] feat: support RemoteComponentDescription --- packages/editor-core/src/editor.ts | 44 ++++++++++++++++++++++++++++++ packages/types/src/assets.ts | 32 ++++++++++++++++++++++ packages/types/src/index.ts | 1 + packages/utils/src/asset.ts | 10 ++++--- 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 packages/types/src/assets.ts diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index c29d03ba0..2c478944c 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -6,10 +6,13 @@ import { KeyType, GetReturnType, HookConfig, + ComponentDescription, + RemoteComponentDescription, } from '@ali/lowcode-types'; import { globalLocale } from './intl'; import * as utils from './utils'; import { obx } from './utils'; +import { AssetsJson, AssetLoader } from '@ali/lowcode-utils'; EventEmitter.defaultMaxListeners = 100; @@ -55,10 +58,51 @@ export class Editor extends EventEmitter implements IEditor { } set(key: KeyType, data: any): void { + if (key === 'assets') { + this.setAssets(data); + return; + } this.context.set(key, data); this.notifyGot(key); } + async setAssets(assets: AssetsJson) { + const { components } = assets; + if (components && components.length) { + const componentDescriptions: ComponentDescription[] = []; + const remoteComponentDescriptions: RemoteComponentDescription[] = []; + components.forEach((component: any) => { + if (!component) { + return; + } + if (component.exportName && component.url) { + remoteComponentDescriptions.push(component); + } else { + componentDescriptions.push(component); + } + }); + assets.components = componentDescriptions; + assets.componentList = assets.componentList || []; + + // 如果有远程组件描述协议,则自动加载并补充到资产包中,同时出发 designer.incrementalAssetsReady 通知组件面板更新数据 + if (remoteComponentDescriptions && remoteComponentDescriptions.length) { + await Promise.all( + remoteComponentDescriptions.map(async (component: any) => { + const { exportName, url } = component; + await (new AssetLoader()).load(url); + if (window[exportName]) { + assets.components = assets.components.concat(window[exportName].components || []); + assets.componentList = assets.componentList.concat(window[exportName].componentList || []); + } + return window[exportName]; + }), + ); + } + } + this.context.set('assets', assets); + this.notifyGot('assets'); + } + onceGot(keyOrType: KeyOrType): Promise> { const x = this.context.get(keyOrType); if (x !== undefined) { diff --git a/packages/types/src/assets.ts b/packages/types/src/assets.ts new file mode 100644 index 000000000..5e2da3167 --- /dev/null +++ b/packages/types/src/assets.ts @@ -0,0 +1,32 @@ +import { NpmInfo } from './npm'; +import { PropConfig } from './prop-config'; +import { Snippet, ComponentMetadata } from './metadata'; + +export interface Package { // 应该被编辑器默认加载,定义组件大包及external资源的信息 + package: string; // 包名 + version: string; // 包版本号 + urls?: string[] | null; // 组件打包后的CDN列表,包含js和css + library: string; // 作为全局变量引用时的名称,和webpack output.library字段含义一样,用来定义全局变量名 +} + +export interface ComponentCategory { // 组件分类 + title: string; // 组件分类title + icon?: string; // 组件分类icon + children?: ComponentItem[] | ComponentCategory[]; // 可能有子分类 +} + +export interface ComponentItem { // 组件 + title: string; // 组件title + componentName?: string; // 组件名 + icon?: string; // 组件icon + snippets?: Snippet[]; +} + +export interface ComponentDescription extends ComponentMetadata { + keywords: string[]; +} + +export interface RemoteComponentDescription { + exportName: string; + url: string; +} diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 6b2472fa4..2c284bf21 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -18,3 +18,4 @@ export * from './node'; export * from './transform-stage'; export * from './code-intermediate'; export * from './code-result'; +export * from './assets'; diff --git a/packages/utils/src/asset.ts b/packages/utils/src/asset.ts index 2c557ff3c..5e428ae7c 100644 --- a/packages/utils/src/asset.ts +++ b/packages/utils/src/asset.ts @@ -1,3 +1,4 @@ +import { Package, ComponentCategory, ComponentDescription, RemoteComponentDescription } from '@ali/lowcode-types'; import { isCSSUrl } from './is-css-url'; import { createDefer } from './create-defer'; import { load, evaluate } from './script'; @@ -55,10 +56,11 @@ export type Asset = AssetList | AssetBundle | AssetItem | URL; export type AssetList = Array; export interface AssetsJson { - packages: Array; - components?: Array; - componentList?: Array; - bizComponentList?: Array; + version: string; // 资产包协议版本号 + packages?: Package[]; // 大包列表,external与package的概念相似,融合在一起 + components: Array; // 所有组件的描述协议列表所有组件的列表 + componentList?: ComponentCategory[]; // 组件分类列表,用来描述物料面板 + bizComponentList?: ComponentCategory[]; // 业务组件分类列表,用来描述物料面板 } export function isAssetItem(obj: any): obj is AssetItem {