feat: 异步加载asset

This commit is contained in:
zude.hzd 2021-03-22 14:19:04 +08:00
parent 424b239e45
commit a5ca12ab69
4 changed files with 116 additions and 16 deletions

View File

@ -255,6 +255,25 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
private _iframe?: HTMLIFrameElement;
buildLibrary(library) {
library = library || this.get('library') as LibraryItem[];
const libraryAsset: AssetList = [];
if (library) {
library.forEach((item) => {
if (item.async) {
this.asyncLibraryMap[item.package] = item;
}
if (item.urls) {
libraryAsset.push(item.urls);
}
});
}
return libraryAsset;
}
async mountContentFrame(iframe: HTMLIFrameElement | null) {
if (!iframe || this._iframe === iframe) {
return;
@ -264,18 +283,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
this._contentWindow = iframe.contentWindow!;
const library = this.get('library') as LibraryItem[];
const libraryAsset: AssetList = [];
if (library) {
library.forEach((item) => {
this.libraryMap[item.package] = item.library;
if (item.async) {
this.asyncLibraryMap[item.package] = item;
}
if (item.urls) {
libraryAsset.push(item.urls);
}
});
}
const libraryAsset: AssetList = this.buildLibrary();
const vendors = [
// required & use once
@ -332,6 +340,11 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
// TODO: dispose the bindings
}
async setupComponents(library) {
const libraryAsset: AssetList = this.buildLibrary(library);
await this.renderer.setupComponents(libraryAsset);
}
setupEvents() {
// TODO: Thinkof move events control to simulator renderer
// just listen special callback
@ -1029,7 +1042,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
const locationData = {
target: container as ParentalNode,
detail,
source: `simulator${ document.id}`,
source: `simulator${document.id}`,
event: e,
};
@ -1042,7 +1055,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
return this.designer.createLocation({
target: document.rootNode,
detail,
source: `simulator${ document.id}`,
source: `simulator${document.id}`,
event: e,
});
}

View File

@ -11,6 +11,7 @@ import {
isNodeSchema,
NodeSchema,
} from '@ali/lowcode-types';
import { megreAssets, AssetsJson } from '@ali/lowcode-utils';
import { Project } from '../project';
import { Node, DocumentModel, insertChildren, isRootNode, ParentalNode, TransformStage } from '../document';
import { ComponentMeta } from '../component-meta';
@ -373,6 +374,25 @@ export class Designer {
this.props = props;
}
async loadIncrementalAssets(incrementalAssets: AssetsJson): void {
const { components, packages } = incrementalAssets;
components && this.buildComponentMetasMap(components);
// 部分异步组件会在外层加载components这里需要进行强制刷新
this.forceUpdateComponentsMap();
await this.project.simulator.setupComponents(packages);
if (components) {
// 合并assets
let assets = this.editor.get('assets');
let newAssets = megreAssets(assets, incrementalAssets);
this.editor.set('assets', newAssets);
}
// 完成加载增量资源后发送事件,方便插件监听并处理相关逻辑
this.editor.emit('designer.incrementalAssetsReady');
}
get(key: string): any {
return this.props ? this.props[key] : null;
}
@ -483,6 +503,13 @@ export class Designer {
return maps;
}
/**
* componentsMap使
*/
private forceUpdateComponentsMap() {
this._componentMetasMap = new Map(this._componentMetasMap);
}
private propsReducers = new Map<TransformStage, PropsReducer[]>();
transformProps(props: CompositeObject | PropsList, node: Node, stage: TransformStage) {

View File

@ -14,7 +14,10 @@ import {
getSubComponent,
compatibleLegaoSchema,
isPlainObject,
AssetLoader,
} from '@ali/lowcode-utils';
import { RootSchema, ComponentSchema, TransformStage, NodeSchema } from '@ali/lowcode-types';
// import { isESModule, isElement, acceptsRef, wrapReactClass, cursor, setNativeSelection } from '@ali/lowcode-utils';
// import { RootSchema, NpmInfo, ComponentSchema, TransformStage, NodeSchema } from '@ali/lowcode-types';
@ -25,7 +28,7 @@ import { createMemoryHistory, MemoryHistory } from 'history';
import Slot from './builtin-components/slot';
import Leaf from './builtin-components/leaf';
import { withQueryParams, parseQuery } from './utils/url';
const loader = new AssetLoader();
export class DocumentInstance {
private instancesMap = new Map<string, ReactInstance[]>();
@ -98,7 +101,7 @@ export class DocumentInstance {
}
get path(): string {
return `/${ this.document.fileName}`;
return `/${this.document.fileName}`;
}
get id() {
@ -349,6 +352,16 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
// return loader.load(asset);
// }
async loadAsyncLibrary(asyncLibraryMap) {
await loader.loadAsyncLibrary(asyncLibraryMap);
this.buildComponents();
}
async setupComponents(asset: Asset) {
await loader.load(asset);
this.buildComponents();
}
getComponent(componentName: string) {
const paths = componentName.split('.');
const subs: string[] = [];

View File

@ -54,6 +54,13 @@ export type Asset = AssetList | AssetBundle | AssetItem | URL;
export type AssetList = Array<Asset | undefined | null>;
export interface AssetsJson {
packages: Array;
components: Array;
componentList?: Array;
bizComponentList?: Array
}
export function isAssetItem(obj: any): obj is AssetItem {
return obj && obj.type;
}
@ -93,6 +100,46 @@ export function assetItem(type: AssetType, content?: string | null, level?: Asse
};
}
export function megreAssets(assets: AssetsJson, increaseAssets: AssetsJson): AssetsJson {
if (!increaseAssets.packages) {
console.error('assets must have packages');
}
if (!increaseAssets.components) {
console.error('assets must have components');
}
assets.packages = [...assets.packages, ...increaseAssets.packages];
assets.components = [...assets.components, ...increaseAssets.components];
megreAssetsComponentList(assets, increaseAssets, 'componentList');
megreAssetsComponentList(assets, increaseAssets, 'bizComponentList');
return assets;
}
function megreAssetsComponentList(assets: AssetsJson, increaseAssets: AssetsJson, listName: String): void {
if (increaseAssets[listName]) {
if (assets[listName]) {
// 根据title进行合并
increaseAssets[listName].map((item) => {
let matchFlag = false;
assets[listName].map((assetItem) => {
if (assetItem.title === item.title) {
assetItem.children = assetItem.children.concat(item.children);
matchFlag = true;
}
return assetItem;
});
!matchFlag && assets[listName].push(item);
return item;
});
}
}
}
export class StylePoint {
private lastContent: string | undefined;