feat(rax-provider): init

This commit is contained in:
wuyue.xht 2020-05-19 21:03:34 +08:00
parent 93cd908adb
commit cb0f3827c7
8 changed files with 208 additions and 0 deletions

View File

@ -0,0 +1,4 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

View File

@ -0,0 +1 @@
# 低代码引擎运行时框架

View File

@ -0,0 +1,11 @@
{
"plugins": [
[
"build-plugin-rax-component",
{
"type": "rax",
"targets": ["web"]
}
]
]
}

View File

@ -0,0 +1,30 @@
{
"name": "@ali/lowcode-rax-provider",
"version": "0.8.14-beta.0",
"description": "Rax Provider for Runtime",
"files": [
"es",
"lib"
],
"main": "lib/index.js",
"module": "es/index.js",
"scripts": {
"start": "build-scripts start",
"build": "build-scripts build"
},
"license": "MIT",
"dependencies": {
"@ali/lowcode-runtime": "^0.8.14-beta.0",
"rax": "1.1.2",
"driver-universal": "^3.1.3",
"rax-use-router": "^3.0.0",
"history": "^4.10.1"
},
"devDependencies": {
"@alib/build-scripts": "^0.1.18",
"build-plugin-rax-component": "^0.2.0"
},
"publishConfig": {
"registry": "https://registry.npm.alibaba-inc.com"
}
}

View File

@ -0,0 +1,5 @@
import RaxProvider from './provider';
import getRouter from './router';
export { getRouter };
export default RaxProvider;

View File

@ -0,0 +1,28 @@
import { createElement, useState, useEffect } from 'rax';
import { app } from '@ali/lowcode-runtime';
export default function LazyComponent(props) {
const [schema, setSchema] = useState(null);
useEffect(() => {
(async () => {
const { getPageData } = props || {};
if (getPageData && !schema) {
const data = await getPageData();
setSchema(data);
}
})();
});
const { getPageData, ...restProps } = props || {};
const Renderer = app.getRenderer();
const Loading = app.getLoading();
if (!Renderer || !schema) {
if (!Loading) {
return null;
}
// loading扩展点
return createElement(Loading);
}
return createElement(Renderer, { schema, loading: Loading ? createElement(Loading) : null, ...restProps });
}

View File

@ -0,0 +1,103 @@
import { createElement, render } from 'rax';
import UniversalDriver from 'driver-universal';
import { app, Provider } from '@ali/lowcode-runtime';
import LazyComponent from './lazy-component';
import getRouter from './router';
export default class RaxProvider extends Provider {
// 定制构造根组件的逻辑,如切换路由机制
createApp() {
const RouterView = this.getRouterView();
let App;
const layoutConfig = this.getLayoutConfig();
if (!layoutConfig || !layoutConfig.componentName) {
App = (props) => (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) =>
createElement(
Layout,
{ ...layoutProps, ...extraLayoutProps },
RouterView ? createElement(RouterView, props) : null,
);
} else {
App = (props) => (RouterView ? createElement(RouterView, props) : null);
}
return App;
}
runApp(App, config) {
render(createElement(App), document.getElementById(config?.containerId || 'App'), { driver: UniversalDriver });
}
// 内置实现 for 动态化渲染
getRouterView() {
const routerConfig = this.getRouterConfig();
if (!routerConfig) {
return null;
}
const routes = [];
let homePageId = this.getHomePage();
Object.keys(routerConfig).forEach((pageId, idx) => {
if (!pageId) {
return;
}
const path = routerConfig[pageId];
routes.push({
path,
component: (props: any) =>
this.getLazyComponent(pageId, {
components: this.getComponents(),
utils: this.getUtils(),
componentsMap: this.getComponentsMapObj(),
...props,
}),
});
if (homePageId) {
return;
}
if (idx === 0 || path === '/') {
homePageId = pageId;
}
});
if (homePageId) {
routes.push({
path: '**',
component: (props) =>
this.getLazyComponent(homePageId, {
components: this.getComponents(),
utils: this.getUtils(),
componentsMap: this.getComponentsMapObj(),
...props,
}),
});
}
const Router = getRouter({
history: this.getHistory(),
routes,
});
const RouterView = (props) => createElement(Router, props);
return RouterView;
}
getLazyComponent(pageId, props) {
if (!pageId) {
return null;
}
if (this.getlazyElement(pageId)) {
return this.getlazyElement(pageId);
}
const lazyElement = createElement(LazyComponent, {
// eslint-disable-next-line no-return-await
getPageData: async () => await this.getPageData(pageId),
key: pageId,
...props,
});
this.setlazyElement(pageId, lazyElement);
return lazyElement;
}
}

View File

@ -0,0 +1,26 @@
import { useRouter } from 'rax-use-router';
import { createHashHistory, createBrowserHistory } from 'history';
const getConfig = (config) => {
let { history } = config;
const { routes } = config;
if (typeof history === 'string') {
if (history === 'hash') {
history = createHashHistory();
} else if (history === 'browser') {
history = createBrowserHistory();
}
}
return () => ({
history,
routes,
});
};
export default function getRouter(config) {
return function Router() {
const configWrapper = getConfig(config);
const { component } = useRouter(configWrapper);
return component;
};
}