feat(render-core): update logger to console

This commit is contained in:
liujuping 2023-11-14 09:55:58 +08:00 committed by 林熠
parent 1020f98756
commit b697ea9ad4
11 changed files with 66 additions and 31 deletions

View File

@ -2,3 +2,4 @@ export * from './host';
export * from './host-view'; export * from './host-view';
export * from './renderer'; export * from './renderer';
export * from './live-editing/live-editing'; export * from './live-editing/live-editing';
export { LowcodeTypes } from './utils/parse-metadata';

View File

@ -46,13 +46,15 @@ function define(propType: any = PropTypes.any, lowcodeType: string | object = {}
return lowcodeCheckType; return lowcodeCheckType;
} }
const LowcodeTypes: any = { export const LowcodeTypes: any = {
...PropTypes, ...PropTypes,
define, define,
}; };
(window as any).PropTypes = LowcodeTypes; (window as any).PropTypes = LowcodeTypes;
(window as any).React.PropTypes = LowcodeTypes; if ((window as any).React) {
(window as any).React.PropTypes = LowcodeTypes;
}
// override primitive type checkers // override primitive type checkers
primitiveTypes.forEach((type) => { primitiveTypes.forEach((type) => {

View File

@ -0,0 +1 @@
module.exports = require('../../babel.config');

View File

@ -4,6 +4,7 @@ import { isReactComponent, cloneEnumerableProperty } from '@alilc/lowcode-utils'
import { debounce } from '../utils/common'; import { debounce } from '../utils/common';
import adapter from '../adapter'; import adapter from '../adapter';
import * as types from '../types/index'; import * as types from '../types/index';
import logger from '../utils/logger';
export interface IComponentHocInfo { export interface IComponentHocInfo {
schema: any; schema: any;
@ -183,7 +184,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
} }
if (!isReactComponent(Comp)) { if (!isReactComponent(Comp)) {
console.error(`${schema.componentName} component may be has errors: `, Comp); logger.error(`${schema.componentName} component may be has errors: `, Comp);
} }
initRerenderEvent({ initRerenderEvent({

View File

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import baseRendererFactory from './base'; import baseRendererFactory from './base';
import { isEmpty } from '../utils'; import { isEmpty } from '../utils';
import { IRendererAppHelper, IBaseRendererProps, IBaseRenderComponent } from '../types'; import { IRendererAppHelper, IBaseRendererProps, IBaseRenderComponent } from '../types';
import logger from '../utils/logger';
export default function addonRendererFactory(): IBaseRenderComponent { export default function addonRendererFactory(): IBaseRenderComponent {
const BaseRenderer = baseRendererFactory(); const BaseRenderer = baseRendererFactory();
@ -32,7 +33,7 @@ export default function addonRendererFactory(): IBaseRenderComponent {
const schema = props.__schema || {}; const schema = props.__schema || {};
this.state = this.__parseData(schema.state || {}); this.state = this.__parseData(schema.state || {});
if (isEmpty(props.config) || !props.config?.addonKey) { if (isEmpty(props.config) || !props.config?.addonKey) {
console.warn('lce addon has wrong config'); logger.warn('lce addon has wrong config');
this.setState({ this.setState({
__hasError: true, __hasError: true,
}); });

View File

@ -56,14 +56,14 @@ export function executeLifeCycleMethod(context: any, schema: IPublicTypeNodeSche
} }
if (typeof fn !== 'function') { if (typeof fn !== 'function') {
console.error(`生命周期${method}类型不符`, fn); logger.error(`生命周期${method}类型不符`, fn);
return; return;
} }
try { try {
return fn.apply(context, args); return fn.apply(context, args);
} catch (e) { } catch (e) {
console.error(`[${schema.componentName}]生命周期${method}出错`, e); logger.error(`[${schema.componentName}]生命周期${method}出错`, e);
} }
} }
@ -208,7 +208,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
async componentDidCatch(...args: any[]) { async componentDidCatch(...args: any[]) {
this.__executeLifeCycleMethod('componentDidCatch', args); this.__executeLifeCycleMethod('componentDidCatch', args);
console.warn(args); logger.warn(args);
} }
reloadDataSource = () => new Promise((resolve, reject) => { reloadDataSource = () => new Promise((resolve, reject) => {
@ -278,7 +278,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
value = this.__parseExpression(value, this); value = this.__parseExpression(value, this);
} }
if (typeof value !== 'function') { if (typeof value !== 'function') {
console.error(`custom method ${key} can not be parsed to a valid function`, value); logger.error(`custom method ${key} can not be parsed to a valid function`, value);
return; return;
} }
this[key] = value.bind(this); this[key] = value.bind(this);
@ -369,7 +369,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
this.setLocale = (loc: string) => { this.setLocale = (loc: string) => {
const setLocaleFn = this.appHelper?.utils?.i18n?.setLocale; const setLocaleFn = this.appHelper?.utils?.i18n?.setLocale;
if (!setLocaleFn || typeof setLocaleFn !== 'function') { if (!setLocaleFn || typeof setLocaleFn !== 'function') {
console.warn('initI18nAPIs Failed, i18n only works when appHelper.utils.i18n.setLocale() exists'); logger.warn('initI18nAPIs Failed, i18n only works when appHelper.utils.i18n.setLocale() exists');
return undefined; return undefined;
} }
return setLocaleFn(loc); return setLocaleFn(loc);
@ -527,7 +527,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
: {}; : {};
if (!Comp) { if (!Comp) {
console.error(`${schema.componentName} component is not found in components list! component list is:`, components || this.props.__container?.components); logger.error(`${schema.componentName} component is not found in components list! component list is:`, components || this.props.__container?.components);
return engine.createElement( return engine.createElement(
engine.getNotFoundComponent(), engine.getNotFoundComponent(),
{ {
@ -749,7 +749,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
__createLoopVirtualDom = (schema: IPublicTypeNodeSchema, scope: any, parentInfo: INodeInfo, idx: number | string) => { __createLoopVirtualDom = (schema: IPublicTypeNodeSchema, scope: any, parentInfo: INodeInfo, idx: number | string) => {
if (isFileSchema(schema)) { if (isFileSchema(schema)) {
console.warn('file type not support Loop'); logger.warn('file type not support Loop');
return null; return null;
} }
if (!Array.isArray(schema.loop)) { if (!Array.isArray(schema.loop)) {

View File

@ -1,4 +1,5 @@
import { IBaseRenderComponent } from '../types'; import { IBaseRenderComponent } from '../types';
import logger from '../utils/logger';
import baseRendererFactory from './base'; import baseRendererFactory from './base';
export default function tempRendererFactory(): IBaseRenderComponent { export default function tempRendererFactory(): IBaseRenderComponent {
@ -41,7 +42,7 @@ export default function tempRendererFactory(): IBaseRenderComponent {
} }
async componentDidCatch(e: any) { async componentDidCatch(e: any) {
console.warn(e); logger.warn(e);
this.__debug(`componentDidCatch - ${this.props.__schema.fileName}`); this.__debug(`componentDidCatch - ${this.props.__schema.fileName}`);
} }

View File

@ -183,13 +183,13 @@ export function transformArrayToMap(arr: any[], key: string, overwrite = true) {
return res; return res;
} }
export function checkPropTypes(value: any, name: string, rule: any, componentName: string) { export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean {
let ruleFunction = rule; let ruleFunction = rule;
if (typeof rule === 'string') { if (typeof rule === 'string') {
ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2); ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2);
} }
if (!ruleFunction || typeof ruleFunction !== 'function') { if (!ruleFunction || typeof ruleFunction !== 'function') {
console.warn('checkPropTypes should have a function type rule argument'); logger.warn('checkPropTypes should have a function type rule argument');
return true; return true;
} }
const err = ruleFunction( const err = ruleFunction(
@ -203,7 +203,7 @@ export function checkPropTypes(value: any, name: string, rule: any, componentNam
ReactPropTypesSecret, ReactPropTypesSecret,
); );
if (err) { if (err) {
console.warn(err); logger.warn(err);
} }
return !err; return !err;
} }

View File

@ -186,7 +186,7 @@ export class DataHelper {
} }
const { headers, ...otherProps } = otherOptionsObj || {}; const { headers, ...otherProps } = otherOptionsObj || {};
if (!req) { if (!req) {
console.warn(`getDataSource API named ${id} not exist`); logger.warn(`getDataSource API named ${id} not exist`);
return; return;
} }
@ -215,7 +215,7 @@ export class DataHelper {
try { try {
callbackFn && callbackFn(res && res[id]); callbackFn && callbackFn(res && res[id]);
} catch (e) { } catch (e) {
console.error('load请求回调函数报错', e); logger.error('load请求回调函数报错', e);
} }
return res && res[id]; return res && res[id];
}) })
@ -223,7 +223,7 @@ export class DataHelper {
try { try {
callbackFn && callbackFn(null, err); callbackFn && callbackFn(null, err);
} catch (e) { } catch (e) {
console.error('load请求回调函数报错', e); logger.error('load请求回调函数报错', e);
} }
return err; return err;
}); });
@ -300,9 +300,9 @@ export class DataHelper {
return dataHandlerFun.call(this.host, data, error); return dataHandlerFun.call(this.host, data, error);
} catch (e) { } catch (e) {
if (id) { if (id) {
console.error(`[${id}]单个请求数据处理函数运行出错`, e); logger.error(`[${id}]单个请求数据处理函数运行出错`, e);
} else { } else {
console.error('请求数据处理函数运行出错', e); logger.error('请求数据处理函数运行出错', e);
} }
} }
} }

View File

@ -1,4 +1,4 @@
// @ts-nocheck import factoryWithTypeCheckers from 'prop-types/factoryWithTypeCheckers';
import { import {
isSchema, isSchema,
isFileSchema, isFileSchema,
@ -18,9 +18,14 @@ import {
parseThisRequiredExpression, parseThisRequiredExpression,
parseI18n, parseI18n,
parseData, parseData,
checkPropTypes,
} from '../../src/utils/common'; } from '../../src/utils/common';
import logger from '../../src/utils/logger'; import logger from '../../src/utils/logger';
var ReactIs = require('react-is');
const PropTypes = factoryWithTypeCheckers(ReactIs.isElement, true);
describe('test isSchema', () => { describe('test isSchema', () => {
it('should be false when empty value is passed', () => { it('should be false when empty value is passed', () => {
expect(isSchema(null)).toBeFalsy(); expect(isSchema(null)).toBeFalsy();
@ -461,4 +466,37 @@ describe('test parseData ', () => {
expect(result.__privateKey).toBeUndefined(); expect(result.__privateKey).toBeUndefined();
}); });
});
describe('checkPropTypes', () => {
it('should validate correctly with valid prop type', () => {
expect(checkPropTypes(123, 'age', PropTypes.number, 'TestComponent')).toBe(true);
expect(checkPropTypes('123', 'age', PropTypes.string, 'TestComponent')).toBe(true);
});
it('should log a warning and return false with invalid prop type', () => {
expect(checkPropTypes(123, 'age', PropTypes.string, 'TestComponent')).toBe(false);
expect(checkPropTypes('123', 'age', PropTypes.number, 'TestComponent')).toBe(false);
});
it('should handle custom rule functions correctly', () => {
const customRule = (props, propName) => {
if (props[propName] !== 123) {
return new Error('Invalid value');
}
};
const result = checkPropTypes(123, 'customProp', customRule, 'TestComponent');
expect(result).toBe(true);
});
it('should interpret and validate a rule given as a string', () => {
const result = checkPropTypes(123, 'age', 'PropTypes.number', 'TestComponent');
expect(result).toBe(true);
});
it('should log a warning for invalid rule type', () => {
const result = checkPropTypes(123, 'age', 123, 'TestComponent');
expect(result).toBe(true);
});
}); });

View File

@ -346,11 +346,6 @@ describe('test DataHelper ', () => {
result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null); result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null);
expect(result).toStrictEqual({ data: 'mockDataValue' }); expect(result).toStrictEqual({ data: 'mockDataValue' });
// test exception
const mockError = jest.fn();
const orginalConsole = global.console;
global.console = { error: mockError };
// exception with id // exception with id
mockDataHandler = { mockDataHandler = {
type: 'JSFunction', type: 'JSFunction',
@ -358,7 +353,6 @@ describe('test DataHelper ', () => {
}; };
result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null); result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null);
expect(result).toBeUndefined(); expect(result).toBeUndefined();
expect(mockError).toBeCalledWith('[fullConfigGet]单个请求数据处理函数运行出错', expect.anything());
// exception without id // exception without id
mockDataHandler = { mockDataHandler = {
@ -367,12 +361,8 @@ describe('test DataHelper ', () => {
}; };
result = dataHelper.handleData(null, mockDataHandler, { data: 'mockDataValue' }, null); result = dataHelper.handleData(null, mockDataHandler, { data: 'mockDataValue' }, null);
expect(result).toBeUndefined(); expect(result).toBeUndefined();
expect(mockError).toBeCalledWith('请求数据处理函数运行出错', expect.anything());
global.console = orginalConsole;
}); });
it('updateConfig should work', () => { it('updateConfig should work', () => {
const mockHost = { stateA: 'aValue'}; const mockHost = { stateA: 'aValue'};
const mockDataSourceConfig = { const mockDataSourceConfig = {