Merge branch 'feat/plugin-preview' into 'components-panel'

refactor: buildComponents

将 buildComponents 添加到 utils

See merge request !910706
This commit is contained in:
度城 2020-07-28 15:43:41 +08:00
commit dfca7c51e0
7 changed files with 33 additions and 203 deletions

View File

@ -1,4 +1,5 @@
import { ReactProvider, Utils } from '@ali/lowcode-runtime';
import { ReactProvider } from '@ali/lowcode-runtime';
import { buildComponents } from '@ali/lowcode-utils';
import appConfig from '../config/app';
import builtInComps from '../config/components';
import componentsMap from '../config/componentsMap';
@ -31,7 +32,7 @@ export default class Preview extends ReactProvider {
layout,
routes,
containerId,
components: { ...builtInComps, ...Utils.buildComponents({ '@alifd/next': 'Next' }, componentsMap) },
components: { ...builtInComps, ...buildComponents({ '@alifd/next': 'Next' }, componentsMap) },
componentsMap,
utils: utils,
constants,

View File

@ -2,85 +2,10 @@ import React, { useState, ComponentType } from 'react';
import { Button, Dialog } from '@alifd/next';
import { PluginProps, NpmInfo } from '@ali/lowcode-types';
import { Designer } from '@ali/lowcode-designer';
import { isReactComponent, isESModule } from '@ali/lowcode-utils';
import { buildComponents } from '@ali/lowcode-utils';
import ReactRenderer from '@ali/lowcode-react-renderer';
import './index.scss';
interface LibraryMap {
[key: string]: string;
}
function accessLibrary(library: string | object) {
if (typeof library !== 'string') {
return library;
}
return (window as any)[library];
}
function getSubComponent(library: any, paths: string[]) {
const l = paths.length;
if (l < 1 || !library) {
return library;
}
let i = 0;
let component: any;
while (i < l) {
const key = paths[i]!;
let ex: any;
try {
component = library[key];
} catch (e) {
ex = e;
component = null;
}
if (i === 0 && component == null && key === 'default') {
if (ex) {
return l === 1 ? library : null;
}
component = library;
} else if (component == null) {
return null;
}
library = component;
i++;
}
return component;
}
function findComponent(libraryMap: LibraryMap, componentName: string, npm?: NpmInfo) {
if (!npm) {
return accessLibrary(componentName);
}
const exportName = npm.exportName || npm.componentName || componentName;
const libraryName = libraryMap[npm.package] || exportName;
const library = accessLibrary(libraryName);
const paths = npm.exportName && npm.subName ? npm.subName.split('.') : [];
if (npm.destructuring) {
paths.unshift(exportName);
} else if (isESModule(library)) {
paths.unshift('default');
}
return getSubComponent(library, paths);
}
function buildComponents(libraryMap: LibraryMap, componentsMap: { [componentName: string]: NpmInfo | ComponentType<any> }) {
const components: any = {
};
Object.keys(componentsMap).forEach((componentName) => {
let component = componentsMap[componentName];
if (isReactComponent(component)) {
components[componentName] = component;
} else {
component = findComponent(libraryMap, componentName, component);
if (component) {
components[componentName] = component;
}
}
});
return components;
}
const SamplePreview = ({ editor }: PluginProps) => {
const [data, setData] = useState({});
const [visible, setVisible] = useState(false);
@ -93,7 +18,7 @@ const SamplePreview = ({ editor }: PluginProps) => {
const assets = await editor.get('assets');
console.info('save schema:', designer, assets);
const libraryMap: LibraryMap = {};
const libraryMap = {};
assets.packages.forEach(({ package, library }) => {
libraryMap[package] = library;
});

View File

@ -3,12 +3,12 @@ import { render as reactRender } from 'react-dom';
import { host } from './host';
import SimulatorRendererView from './renderer-view';
import { computed, obx } from '@recore/obx';
import { Asset, isReactComponent } from '@ali/lowcode-utils';
import { Asset } from '@ali/lowcode-utils';
import { getClientRects } from './utils/get-client-rects';
import loader from './utils/loader';
import { reactFindDOMNodes, FIBER_KEY } from './utils/react-find-dom-nodes';
import { isESModule, isElement, cursor, setNativeSelection } from '@ali/lowcode-utils';
import { RootSchema, NpmInfo, ComponentSchema, TransformStage } from '@ali/lowcode-types';
import { isElement, cursor, setNativeSelection, buildComponents, getSubComponent } from '@ali/lowcode-utils';
import { RootSchema, ComponentSchema, TransformStage } from '@ali/lowcode-types';
// just use types
import { BuiltinSimulatorRenderer, NodeInstance, Component } from '@ali/lowcode-designer';
import Slot from './builtin-components/slot';
@ -74,7 +74,10 @@ export class SimulatorRenderer implements BuiltinSimulatorRenderer {
}
private _libraryMap: { [key: string]: string } = {};
private buildComponents() {
this._components = buildComponents(this._libraryMap, this._componentsMap);
this._components = {
...builtinComponents,
...buildComponents(this._libraryMap, this._componentsMap)
};
}
@obx.ref private _components: any = {};
@computed get components(): object {
@ -315,70 +318,6 @@ export class SimulatorRenderer implements BuiltinSimulatorRenderer {
}
}
function accessLibrary(library: string | object) {
if (typeof library !== 'string') {
return library;
}
return (window as any)[library];
}
function getSubComponent(library: any, paths: string[]) {
const l = paths.length;
if (l < 1 || !library) {
return library;
}
let i = 0;
let component: any;
while (i < l) {
const key = paths[i]!;
let ex: any;
try {
component = library[key];
} catch (e) {
ex = e;
component = null;
}
if (i === 0 && component == null && key === 'default') {
if (ex) {
return l === 1 ? library : null;
}
component = library;
} else if (component == null) {
return null;
}
library = component;
i++;
}
return component;
}
function findComponent(libraryMap: LibraryMap, componentName: string, npm?: NpmInfo) {
if (!npm) {
return accessLibrary(componentName);
}
// libraryName the key access to global
// export { exportName } from xxx exportName === global.libraryName.exportName
// export exportName from xxx exportName === global.libraryName.default || global.libraryName
// export { exportName as componentName } from package
// if exportName == null exportName === componentName;
// const componentName = exportName.subName, if exportName empty subName donot use
const exportName = npm.exportName || npm.componentName || componentName;
const libraryName = libraryMap[npm.package] || exportName;
const library = accessLibrary(libraryName);
const paths = npm.exportName && npm.subName ? npm.subName.split('.') : [];
if (npm.destructuring) {
paths.unshift(exportName);
} else if (isESModule(library)) {
paths.unshift('default');
}
return getSubComponent(library, paths);
}
export interface LibraryMap {
[key: string]: string;
}
// Slot/Leaf and Fragment|FunctionComponent polyfill(ref)
const builtinComponents = {
@ -386,24 +325,6 @@ const builtinComponents = {
Leaf,
};
function buildComponents(libraryMap: LibraryMap, componentsMap: { [componentName: string]: NpmInfo | ComponentType<any> }) {
const components: any = {
...builtinComponents
};
Object.keys(componentsMap).forEach((componentName) => {
let component = componentsMap[componentName];
if (isReactComponent(component)) {
components[componentName] = component;
} else {
component = findComponent(libraryMap, componentName, component);
if (component) {
components[componentName] = component;
}
}
});
return components;
}
let REACT_KEY = '';
function cacheReactKey(el: Element): Element {
if (REACT_KEY !== '') {

View File

@ -1,5 +1,4 @@
import Provider from './core/provider';
import app from './core';
import * as Utils from './utils';
export { app, Provider, Utils };
export { app, Provider };

View File

@ -1 +0,0 @@
export * from './assets';

View File

@ -1,5 +1,10 @@
function isESModule(obj: any): obj is { [key: string]: any } {
return obj && obj.__esModule;
import { ComponentType } from 'react';
import { NpmInfo} from '@ali/lowcode-types';
import { isReactComponent } from './is-react';
import { isESModule } from './is-es-module';
interface LibraryMap {
[key: string]: string;
}
function accessLibrary(library: string | object) {
@ -10,7 +15,7 @@ function accessLibrary(library: string | object) {
return (window as any)[library];
}
function getSubComponent(library: any, paths: string[]) {
export function getSubComponent(library: any, paths: string[]) {
const l = paths.length;
if (l < 1 || !library) {
return library;
@ -62,40 +67,19 @@ function findComponent(libraryMap: LibraryMap, componentName: string, npm?: NpmI
return getSubComponent(library, paths);
}
export interface LibraryMap {
[key: string]: string;
}
export interface NpmInfo {
componentName?: string;
package: string;
version: string;
destructuring?: boolean;
exportName?: string;
subName?: string;
main?: string;
}
export function buildComponents(
libraryMap: LibraryMap,
componentsMap: { [componentName: string]: NpmInfo } | NpmInfo[],
) {
const components: any = {};
if (componentsMap && Array.isArray(componentsMap)) {
const compMapObj: any = {};
componentsMap.forEach((item: NpmInfo) => {
if (!item || !item.componentName) {
return;
}
compMapObj[item.componentName] = item;
});
componentsMap = compMapObj;
}
export function buildComponents(libraryMap: LibraryMap, componentsMap: { [componentName: string]: NpmInfo | ComponentType<any> }) {
const components: any = {
};
Object.keys(componentsMap).forEach((componentName) => {
const component = findComponent(libraryMap, componentName, (componentsMap as any)[componentName]);
if (component) {
let component = componentsMap[componentName];
if (isReactComponent(component)) {
components[componentName] = component;
} else {
component = findComponent(libraryMap, componentName, component);
if (component) {
components[componentName] = component;
}
}
});
return components;
}
}

View File

@ -18,3 +18,4 @@ export * from './set-prototype-of';
export * from './shallow-equal';
export * from './svg-icon';
export * from './unique-id';
export * from './build-components';