Merge branch 'develop' into release/1.1.11-beta

This commit is contained in:
JackLian 2023-10-16 14:35:53 +08:00
commit 57267ed823
8 changed files with 77 additions and 68 deletions

View File

@ -58,7 +58,7 @@ sidebar_position: 1
## 协议的作用
基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升各平台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。
基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升各平台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。
### 打破物料孤岛

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-engine-docs",
"version": "1.1.10",
"version": "1.1.11",
"description": "低代码引擎版本化文档",
"license": "MIT",
"files": [

View File

@ -31,6 +31,7 @@ exports[`Base should be render Text 1`] = `
behavior="NORMAL"
componentId="node_ockvuu8u916"
fieldId="text_kvuu9gl2"
forwardRef={[Function]}
maxLine={0}
showTitle={false}
>

View File

@ -1,20 +1,72 @@
import { cloneEnumerableProperty } from '@alilc/lowcode-utils';
import adapter from '../adapter';
import { IBaseRendererInstance, IRendererProps } from '../types';
export function compWrapper(Comp: any) {
function patchDidCatch(Comp: any, { baseRenderer }: { baseRenderer: IBaseRendererInstance }) {
if (Comp.patchedCatch) {
return;
}
Comp.patchedCatch = true;
const { PureComponent } = adapter.getRuntime();
// Rax 的 getDerivedStateFromError 有 BUG这里先用 componentDidCatch 来替代
// @see https://github.com/alibaba/rax/issues/2211
const originalDidCatch = Comp.prototype.componentDidCatch;
Comp.prototype.componentDidCatch = function didCatch(this: any, error: Error, errorInfo: any) {
this.setState({ engineRenderError: true, error });
if (originalDidCatch && typeof originalDidCatch === 'function') {
originalDidCatch.call(this, error, errorInfo);
}
};
const { engine } = baseRenderer.context;
const originRender = Comp.prototype.render;
Comp.prototype.render = function () {
if (this.state && this.state.engineRenderError) {
this.state.engineRenderError = false;
return engine.createElement(engine.getFaultComponent(), {
...this.props,
error: this.state.error,
componentName: this.props._componentName,
});
}
return originRender.call(this);
};
if (!(Comp.prototype instanceof PureComponent)) {
const originShouldComponentUpdate = Comp.prototype.shouldComponentUpdate;
Comp.prototype.shouldComponentUpdate = function (nextProps: IRendererProps, nextState: any) {
if (nextState && nextState.engineRenderError) {
return true;
}
return originShouldComponentUpdate
? originShouldComponentUpdate.call(this, nextProps, nextState)
: true;
};
}
}
export function compWrapper(Comp: any, options: { baseRenderer: IBaseRendererInstance }) {
const { createElement, Component, forwardRef } = adapter.getRuntime();
if (
Comp?.prototype?.isReactComponent || // react
Comp?.prototype?.setState || // rax
Comp?.prototype instanceof Component
) {
patchDidCatch(Comp, options);
return Comp;
}
class Wrapper extends Component {
// constructor(props: any, context: any) {
// super(props, context);
// }
render() {
return createElement(Comp, this.props);
return createElement(Comp, { ...this.props, ref: this.props.forwardRef });
}
}
(Wrapper as any).displayName = Comp.displayName;
return cloneEnumerableProperty(forwardRef((props: any, ref: any) => {
return createElement(Wrapper, { ...props, forwardRef: ref });
}), Comp);
patchDidCatch(Wrapper, options);
return cloneEnumerableProperty(
forwardRef((props: any, ref: any) => {
return createElement(Wrapper, { ...props, forwardRef: ref });
}),
Comp,
);
}

View File

@ -23,7 +23,6 @@ import {
transformStringToFunction,
checkPropTypes,
getI18n,
canAcceptsRef,
getFileCssName,
capitalizeFirstLetter,
DataHelper,
@ -616,11 +615,8 @@ export default function baseRendererFactory(): IBaseRenderComponent {
});
});
// 对于不可以接收到 ref 的组件需要做特殊处理
if (!canAcceptsRef(Comp)) {
Comp = compWrapper(Comp);
components[schema.componentName] = Comp;
}
Comp = compWrapper(Comp, { baseRenderer: this });
components[schema.componentName] = Comp;
otherProps.ref = (ref: any) => {
this.$(props.fieldId || props.ref, ref); // 收集ref

View File

@ -105,55 +105,7 @@ export default function rendererFactory(): IRenderComponent {
return SetComponent;
}
patchDidCatch(SetComponent: any) {
if (!this.isValidComponent(SetComponent)) {
return;
}
if (SetComponent.patchedCatch) {
return;
}
if (!SetComponent.prototype) {
return;
}
SetComponent.patchedCatch = true;
// Rax 的 getDerivedStateFromError 有 BUG这里先用 componentDidCatch 来替代
// @see https://github.com/alibaba/rax/issues/2211
const originalDidCatch = SetComponent.prototype.componentDidCatch;
SetComponent.prototype.componentDidCatch = function didCatch(this: any, error: Error, errorInfo: any) {
this.setState({ engineRenderError: true, error });
if (originalDidCatch && typeof originalDidCatch === 'function') {
originalDidCatch.call(this, error, errorInfo);
}
};
const engine = this;
const originRender = SetComponent.prototype.render;
SetComponent.prototype.render = function () {
if (this.state && this.state.engineRenderError) {
this.state.engineRenderError = false;
return engine.createElement(engine.getFaultComponent(), {
...this.props,
error: this.state.error,
componentName: this.props._componentName
});
}
return originRender.call(this);
};
if(!(SetComponent.prototype instanceof PureComponent)) {
const originShouldComponentUpdate = SetComponent.prototype.shouldComponentUpdate;
SetComponent.prototype.shouldComponentUpdate = function (nextProps: IRendererProps, nextState: any) {
if (nextState && nextState.engineRenderError) {
return true;
}
return originShouldComponentUpdate ? originShouldComponentUpdate.call(this, nextProps, nextState) : true;
};
}
}
createElement(SetComponent: any, props: any, children?: any) {
// TODO: enable in runtime mode?
this.patchDidCatch(SetComponent);
return (this.props.customCreateElement || createElement)(SetComponent, props, children);
}

View File

@ -335,7 +335,6 @@ export interface IRenderComponent {
componentDidCatch(e: any): Promise<void> | void;
shouldComponentUpdate(nextProps: IRendererProps): boolean;
isValidComponent(SetComponent: any): any;
patchDidCatch(SetComponent: any): void;
createElement(SetComponent: any, props: any, children?: any): any;
getNotFoundComponent(): any;
getFaultComponent(): any;

View File

@ -10,10 +10,10 @@ export function isReactClass(obj: any): obj is ComponentClass<any> {
}
export function acceptsRef(obj: any): boolean {
return obj?.prototype?.isReactComponent || (obj.$$typeof && obj.$$typeof === REACT_FORWARD_REF_TYPE);
return obj?.prototype?.isReactComponent || isForwardOrMemoForward(obj);
}
function isForwardRefType(obj: any): boolean {
export function isForwardRefType(obj: any): boolean {
return obj?.$$typeof && obj?.$$typeof === REACT_FORWARD_REF_TYPE;
}
@ -21,6 +21,15 @@ function isMemoType(obj: any): boolean {
return obj?.$$typeof && obj.$$typeof === REACT_MEMO_TYPE;
}
export function isForwardOrMemoForward(obj: any): boolean {
return obj?.$$typeof && (
// React.forwardRef(..)
isForwardRefType(obj) ||
// React.memo(React.forwardRef(..))
(isMemoType(obj) && isForwardRefType(obj.type))
);
}
export function isReactComponent(obj: any): obj is ComponentType<any> {
if (!obj) {
return false;