mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-04-20 12:28:08 +00:00
chore: 抽离React
This commit is contained in:
parent
0e50a2056a
commit
8e361967e0
@ -1,9 +1,5 @@
|
|||||||
{
|
{
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"build-plugin-component",
|
"build-plugin-component"
|
||||||
"build-plugin-fusion",
|
|
||||||
["build-plugin-moment-locales", {
|
|
||||||
"locales": ["zh-cn"]
|
|
||||||
}]
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ali/lowcode-runtime",
|
"name": "@ali/lowcode-runtime",
|
||||||
"version": "0.8.12",
|
"version": "0.8.14",
|
||||||
"description": "Runtime for Ali lowCode engine",
|
"description": "Runtime for Ali lowCode engine",
|
||||||
"files": [
|
"files": [
|
||||||
"es",
|
"es",
|
||||||
@ -25,15 +25,13 @@
|
|||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ali/recore": "^1.6.9",
|
"@ali/offline-events": "^1.0.0",
|
||||||
"@ali/offline-events": "^1.0.0"
|
"history": "^4.10.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alib/build-scripts": "^0.1.18",
|
"@alib/build-scripts": "^0.1.18",
|
||||||
"@types/node": "^13.7.1",
|
"@types/node": "^13.7.1",
|
||||||
"@types/react": "^16",
|
"build-plugin-component": "^0.2.16"
|
||||||
"@types/react-dom": "^16",
|
|
||||||
"build-plugin-component": "^0.2.11"
|
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"registry": "https://registry.npm.alibaba-inc.com"
|
"registry": "https://registry.npm.alibaba-inc.com"
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { ReactType } from 'react';
|
|
||||||
import Provider from './provider';
|
import Provider from './provider';
|
||||||
|
|
||||||
export interface ILayoutOptions {
|
export interface ILayoutOptions {
|
||||||
@ -7,16 +6,16 @@ export interface ILayoutOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class Container {
|
export default class Container {
|
||||||
private renderer: ReactType | null = null;
|
private renderer: any = null;
|
||||||
private layouts: { [key: string]: { content: ReactType; props: any } } = {};
|
private layouts: { [key: string]: { content: any; props: any } } = {};
|
||||||
private loading: ReactType | null = null;
|
private loading: any = null;
|
||||||
private provider: any;
|
private provider: any;
|
||||||
|
|
||||||
registerRenderer(renderer: ReactType): any {
|
registerRenderer(renderer: any): any {
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLayout(Layout: ReactType, options: ILayoutOptions): any {
|
registerLayout(Layout: any, options: ILayoutOptions): any {
|
||||||
if (!options) {
|
if (!options) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -27,7 +26,7 @@ export default class Container {
|
|||||||
this.layouts[componentName] = { content: Layout, props };
|
this.layouts[componentName] = { content: Layout, props };
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLoading(component: ReactType) {
|
registerLoading(component: any) {
|
||||||
if (!component) {
|
if (!component) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -50,11 +49,11 @@ export default class Container {
|
|||||||
return this.layouts[componentName];
|
return this.layouts[componentName];
|
||||||
}
|
}
|
||||||
|
|
||||||
getRenderer(): ReactType | null {
|
getRenderer(): any {
|
||||||
return this.renderer;
|
return this.renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLoading(): ReactType | null {
|
getLoading(): any {
|
||||||
return this.loading;
|
return this.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { ReactType } from 'react';
|
|
||||||
import Container, { ILayoutOptions } from './container';
|
import Container, { ILayoutOptions } from './container';
|
||||||
import { IProvider } from './provider';
|
import { IProvider } from './provider';
|
||||||
import run from './run';
|
import runApp from './runApp';
|
||||||
|
|
||||||
class App {
|
class App {
|
||||||
private container: Container;
|
private container: Container;
|
||||||
@ -11,18 +10,18 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
run();
|
runApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
registerRenderer(renderer: ReactType): any {
|
registerRenderer(renderer: any): any {
|
||||||
this.container.registerRenderer(renderer);
|
this.container.registerRenderer(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLayout(Layout: ReactType, options: ILayoutOptions): any {
|
registerLayout(Layout: any, options: ILayoutOptions): any {
|
||||||
this.container.registerLayout(Layout, options);
|
this.container.registerLayout(Layout, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLoading(component: ReactType) {
|
registerLoading(component: any) {
|
||||||
this.container.registerLoading(component);
|
this.container.registerLoading(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,11 +33,11 @@ class App {
|
|||||||
return this.container.getLayout(componentName);
|
return this.container.getLayout(componentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRenderer(): ReactType | null {
|
getRenderer(): any | null {
|
||||||
return this.container.getRenderer();
|
return this.container.getRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
getLoading(): ReactType | null {
|
getLoading(): any | null {
|
||||||
return this.container.getLoading();
|
return this.container.getLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { IAppConfig, IUtils, IComponents, HistoryMode } from '../run';
|
import { IAppConfig, IUtils, IComponents, HistoryMode } from './runApp';
|
||||||
import EventEmitter from '@ali/offline-events';
|
import EventEmitter from '@ali/offline-events';
|
||||||
|
|
||||||
interface IConstants {
|
interface IConstants {
|
||||||
@ -110,6 +110,7 @@ export interface IProvider {
|
|||||||
getPageData(pageId: string): Promise<ComponentModel | undefined>;
|
getPageData(pageId: string): Promise<ComponentModel | undefined>;
|
||||||
getLazyComponent(pageId: string, props: any): any;
|
getLazyComponent(pageId: string, props: any): any;
|
||||||
createApp(): void;
|
createApp(): void;
|
||||||
|
runApp(App: any, config: IAppConfig): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Provider implements IProvider {
|
export default class Provider implements IProvider {
|
||||||
@ -197,6 +198,10 @@ export default class Provider implements IProvider {
|
|||||||
throw new Error('Method called "createApp" not implemented.');
|
throw new Error('Method called "createApp" not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runApp(App: any, config: IAppConfig) {
|
||||||
|
throw new Error('Method called "runApp" not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
registerComponents(components: IComponents | undefined) {
|
registerComponents(components: IComponents | undefined) {
|
||||||
if (!components) {
|
if (!components) {
|
||||||
return;
|
return;
|
||||||
@ -1,100 +0,0 @@
|
|||||||
import { createElement, ReactType, ReactElement } from 'react';
|
|
||||||
import { Router } from '@ali/recore';
|
|
||||||
import app from '../../index';
|
|
||||||
import Provider from '..';
|
|
||||||
import LazyComponent from './lazy-component';
|
|
||||||
|
|
||||||
export default class ReactProvider extends Provider {
|
|
||||||
// 定制构造根组件的逻辑,如切换路由机制
|
|
||||||
createApp() {
|
|
||||||
const RouterView = this.getRouterView();
|
|
||||||
let App;
|
|
||||||
const layoutConfig = this.getLayoutConfig();
|
|
||||||
if (!layoutConfig || !layoutConfig.componentName) {
|
|
||||||
App = (props: any) => (RouterView ? createElement(RouterView, { ...props }) : null);
|
|
||||||
return App;
|
|
||||||
}
|
|
||||||
const { componentName: layoutName, props: layoutProps } = layoutConfig;
|
|
||||||
const { content: Layout, props: extraLayoutProps } = app.getLayout(layoutName) || {};
|
|
||||||
const sectionalRender = this.isSectionalRender();
|
|
||||||
if (!sectionalRender && Layout) {
|
|
||||||
App = (props: any) =>
|
|
||||||
createElement(
|
|
||||||
Layout,
|
|
||||||
{ ...layoutProps, ...extraLayoutProps },
|
|
||||||
RouterView ? createElement(RouterView, props) : null,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
App = (props: any) => (RouterView ? createElement(RouterView, props) : null);
|
|
||||||
}
|
|
||||||
return App;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 内置实现 for 动态化渲染
|
|
||||||
getRouterView(): ReactType | null {
|
|
||||||
const routerConfig = this.getRouterConfig();
|
|
||||||
if (!routerConfig) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const routes: Array<{
|
|
||||||
path: string;
|
|
||||||
children: any;
|
|
||||||
exact: boolean;
|
|
||||||
defined: { keepAlive: boolean; [key: string]: any };
|
|
||||||
}> = [];
|
|
||||||
let homePageId = this.getHomePage();
|
|
||||||
Object.keys(routerConfig).forEach((pageId: string, idx: number) => {
|
|
||||||
if (!pageId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const path = routerConfig[pageId];
|
|
||||||
routes.push({
|
|
||||||
path,
|
|
||||||
children: (props: any) => this.getLazyComponent(pageId, props),
|
|
||||||
exact: true,
|
|
||||||
defined: { keepAlive: true },
|
|
||||||
});
|
|
||||||
if (homePageId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (idx === 0 || path === '/') {
|
|
||||||
homePageId = pageId;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (homePageId) {
|
|
||||||
routes.push({
|
|
||||||
path: '**',
|
|
||||||
children: (props: any) => this.getLazyComponent(homePageId, { ...props }),
|
|
||||||
exact: true,
|
|
||||||
defined: { keepAlive: true },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const RouterView = (props: any) => {
|
|
||||||
return createElement(Router as any, {
|
|
||||||
routes,
|
|
||||||
components: this.getComponents(),
|
|
||||||
utils: this.getUtils(),
|
|
||||||
componentsMap: this.getComponentsMapObj(),
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return RouterView;
|
|
||||||
}
|
|
||||||
|
|
||||||
getLazyComponent(pageId: string, props: any): ReactElement | null {
|
|
||||||
if (!pageId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (this.getlazyElement(pageId)) {
|
|
||||||
return this.getlazyElement(pageId);
|
|
||||||
} else {
|
|
||||||
const lazyElement = createElement(LazyComponent as any, {
|
|
||||||
getPageData: async () => await this.getPageData(pageId),
|
|
||||||
key: pageId,
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
this.setlazyElement(pageId, lazyElement);
|
|
||||||
return lazyElement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import { Component, createElement } from 'react';
|
|
||||||
import app from '../../index';
|
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
getPageData: () => any;
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IState {
|
|
||||||
schema: object | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class LazyComponent extends Component<IProps, IState> {
|
|
||||||
constructor(props: IProps) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
schema: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async componentDidMount() {
|
|
||||||
const { getPageData } = this.props;
|
|
||||||
if (getPageData && !this.state.schema) {
|
|
||||||
const schema = await getPageData();
|
|
||||||
this.setState({ schema });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { getPageData, ...restProps } = this.props;
|
|
||||||
const { schema } = this.state;
|
|
||||||
const Renderer = app.getRenderer();
|
|
||||||
const Loading = app.getLoading();
|
|
||||||
if (!Renderer || !schema) {
|
|
||||||
if (!Loading) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// loading扩展点
|
|
||||||
return createElement(Loading);
|
|
||||||
}
|
|
||||||
return createElement(Renderer as any, { schema, loading: Loading ? createElement(Loading) : null, ...restProps });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
import { ReactType } from 'react';
|
import { HashHistoryBuildOptions, BrowserHistoryBuildOptions, MemoryHistoryBuildOptions } from 'history';
|
||||||
import { runApp } from '@ali/recore';
|
|
||||||
import { HashHistoryBuildOptions, BrowserHistoryBuildOptions, MemoryHistoryBuildOptions } from '@recore/history';
|
|
||||||
import app from './index';
|
import app from './index';
|
||||||
|
|
||||||
export type HistoryOptions = {
|
export type HistoryOptions = {
|
||||||
@ -8,7 +6,7 @@ export type HistoryOptions = {
|
|||||||
} & (HashHistoryBuildOptions | BrowserHistoryBuildOptions | MemoryHistoryBuildOptions);
|
} & (HashHistoryBuildOptions | BrowserHistoryBuildOptions | MemoryHistoryBuildOptions);
|
||||||
|
|
||||||
export interface IComponents {
|
export interface IComponents {
|
||||||
[key: string]: ReactType;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IUtils {
|
export interface IUtils {
|
||||||
@ -22,34 +20,35 @@ export interface IAppConfig {
|
|||||||
components?: IComponents;
|
components?: IComponents;
|
||||||
utils?: IUtils;
|
utils?: IUtils;
|
||||||
containerId?: string;
|
containerId?: string;
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRecoreAppConfig {
|
// export interface IRecoreAppConfig {
|
||||||
history?: HistoryMode;
|
// history?: HistoryMode;
|
||||||
globalComponents?: IComponents;
|
// globalComponents?: IComponents;
|
||||||
globalUtils?: IUtils;
|
// globalUtils?: IUtils;
|
||||||
containerId?: string;
|
// containerId?: string;
|
||||||
}
|
// }
|
||||||
|
|
||||||
function transformConfig(config: IAppConfig | (() => IAppConfig)): IRecoreAppConfig {
|
// function transformConfig(config: IAppConfig | (() => IAppConfig)): IRecoreAppConfig {
|
||||||
if (!config) {
|
// if (!config) {
|
||||||
return {};
|
// return {};
|
||||||
}
|
// }
|
||||||
if (typeof config === 'function') {
|
// if (typeof config === 'function') {
|
||||||
config = config();
|
// config = config();
|
||||||
}
|
// }
|
||||||
return {
|
// return {
|
||||||
history: config.history,
|
// history: config.history,
|
||||||
globalComponents: config.components,
|
// globalComponents: config.components,
|
||||||
globalUtils: config.utils,
|
// globalUtils: config.utils,
|
||||||
containerId: config.containerId,
|
// containerId: config.containerId,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
export default function run() {
|
export default function runApp() {
|
||||||
const provider = app.getProvider();
|
const provider = app.getProvider();
|
||||||
if (!provider) {
|
if (!provider) {
|
||||||
throw new Error('');
|
throw new Error('Please register class Provider');
|
||||||
}
|
}
|
||||||
provider.onReady(() => {
|
provider.onReady(() => {
|
||||||
const promise = provider.async();
|
const promise = provider.async();
|
||||||
@ -58,8 +57,7 @@ export default function run() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const App = provider.createApp();
|
const App = provider.createApp();
|
||||||
config = transformConfig(config);
|
provider.runApp(App, config);
|
||||||
runApp(App, config);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1,7 +1,5 @@
|
|||||||
import { navigator, Router } from '@ali/recore';
|
|
||||||
import Provider from './core/provider';
|
import Provider from './core/provider';
|
||||||
import ReactProvider from './core/provider/react';
|
|
||||||
import app from './core';
|
import app from './core';
|
||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
|
|
||||||
export { app, Router, Provider, ReactProvider, navigator, Utils };
|
export { app, Provider, Utils };
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user