mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 03:48:13 +08:00
feat: amis Debug 辅助工具 (#3370)
* feat: debug 草稿 * 补充文档及增加 inspect 功能 * 增加 data 查看 * 增加 log 分类 * 增加 resize 功能 * 修复报错 * 去掉无用依赖 * 避免报错 Co-authored-by: wuduoyi <nwind@iMac-Pro.local>
This commit is contained in:
parent
7a8b11dcb0
commit
afaa9384d2
23
docs/zh-CN/extend/debug.md
Normal file
23
docs/zh-CN/extend/debug.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
title: Debug 工具
|
||||
---
|
||||
|
||||
> 1.6.1 及以上版本
|
||||
|
||||
amis 内置了 Debug 功能,可以查看组件内部运行日志,方便分析问题,目前在文档右侧就有显示。
|
||||
|
||||
## 开启方法
|
||||
|
||||
默认不会开启这个功能,可以通过下面两种方式开启:
|
||||
|
||||
1. 配置全局变量 `enableAMISDebug` 的值为 `true`,比如 `window.enableAMISDebug = true`。
|
||||
2. 在页面 URL 参数中加上 `amisDebug=1`,比如 `http://xxx.com/?amisDebug=1`。
|
||||
|
||||
开启之后,在页面右侧就会显示。
|
||||
|
||||
## 目前功能
|
||||
|
||||
目前 Debug 工具提供了两个功能:
|
||||
|
||||
1. 运行日志,主要是 api 及数据转换的日志
|
||||
2. 查看组件数据链,Debug 工具展开后,点击任意组件就能看到这个组件的数据链
|
@ -103,6 +103,8 @@
|
||||
})();
|
||||
}
|
||||
|
||||
window.enableAMISDebug = true;
|
||||
|
||||
/* @require ./index.jsx 标记为同步依赖,提前加载 */
|
||||
amis.require(['./index.jsx'], function (app) {
|
||||
var initialState = {};
|
||||
|
@ -409,6 +409,7 @@ $zindex-contextmenu: 1500 !default;
|
||||
$zindex-tooltip: 1600 !default;
|
||||
$zindex-toast: 2000 !default;
|
||||
$zindex-top: 3000 !default;
|
||||
$zindex-debug: 4000 !default;
|
||||
|
||||
$Form--horizontal-columns: 12;
|
||||
$Table-strip-bg: lighten(#f6f8f8, 1%) !default;
|
||||
|
167
scss/components/_debug.scss
Normal file
167
scss/components/_debug.scss
Normal file
@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Debug 模块的 UI,由于没法使用任何主题,所以这里使用独立配色风格
|
||||
*/
|
||||
|
||||
.AMISDebug {
|
||||
position: fixed;
|
||||
z-index: $zindex-debug;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100vh;
|
||||
width: 24px;
|
||||
|
||||
h3 {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.primary {
|
||||
color: #009fff;
|
||||
}
|
||||
|
||||
&-header {
|
||||
padding: var(--Drawer-header-padding);
|
||||
background: var(--Drawer-header-bg);
|
||||
border-bottom: var(--Drawer-content-borderWidth) solid
|
||||
var(--Drawer-header-borderColor);
|
||||
}
|
||||
|
||||
&-hoverBox {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
outline: 1px dashed #1c76c4;
|
||||
}
|
||||
|
||||
&-activeBox {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
outline: 1px #1c76c4;
|
||||
}
|
||||
|
||||
&-tab {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&-tab > button {
|
||||
color: inherit;
|
||||
background: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: var(--gap-sm) var(--gap-md);
|
||||
transition: 0.3s;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
&-tab > button:hover {
|
||||
color: #e7e7e7;
|
||||
}
|
||||
|
||||
&-tab > button.active {
|
||||
color: #e7e7e7;
|
||||
border-bottom-color: #e7e7e7;
|
||||
}
|
||||
|
||||
&-toggle {
|
||||
background: var(--body-bg);
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
width: 24px;
|
||||
height: 48px;
|
||||
box-shadow: rgba(0, 0, 0, 0.24) -2px 0px 4px 0px;
|
||||
border-top-left-radius: 12px;
|
||||
border-bottom-left-radius: 12px;
|
||||
padding-top: 14px;
|
||||
padding-left: 6px;
|
||||
cursor: pointer;
|
||||
i {
|
||||
color: var(--text-color);
|
||||
}
|
||||
&:hover {
|
||||
i {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-resize {
|
||||
position: absolute;
|
||||
width: 4px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
cursor: col-resize;
|
||||
&:hover {
|
||||
background: #75715e;
|
||||
}
|
||||
}
|
||||
|
||||
&-changePosition {
|
||||
position: absolute;
|
||||
font-size: 18px;
|
||||
right: 40px;
|
||||
top: var(--gap-sm);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-close {
|
||||
position: absolute;
|
||||
font-size: 18px;
|
||||
right: var(--gap-sm);
|
||||
top: var(--gap-sm);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.is-expanded {
|
||||
width: 420px;
|
||||
overflow: auto;
|
||||
background: #272821;
|
||||
color: #cccccc;
|
||||
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
|
||||
.AMISDebug-toggle {
|
||||
display: none;
|
||||
}
|
||||
.AMISDebug-content {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-left {
|
||||
left: 0;
|
||||
.AMISDebug-resize {
|
||||
left: unset;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-log {
|
||||
padding: var(--gap-sm);
|
||||
button {
|
||||
cursor: pointer;
|
||||
background: #0e639c;
|
||||
flex-grow: 1;
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 6px 11px;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
max-width: 300px;
|
||||
border: none;
|
||||
}
|
||||
button:hover {
|
||||
background: #1177bb;
|
||||
}
|
||||
}
|
||||
|
||||
&-inspect {
|
||||
padding: var(--gap-sm);
|
||||
}
|
||||
}
|
@ -123,4 +123,6 @@
|
||||
@import '../components/formula';
|
||||
@import '../components/timeline';
|
||||
|
||||
@import '../components/debug';
|
||||
|
||||
@import '../utilities';
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
import {asFormItem} from './renderers/Form/Item';
|
||||
import {renderChild, renderChildren} from './Root';
|
||||
import {Schema, SchemaNode} from './types';
|
||||
import {DebugWrapper, enableAMISDebug} from './utils/debug';
|
||||
import getExprProperties from './utils/filter-schema';
|
||||
import {anyChanged, chainEvents, autobind} from './utils/helper';
|
||||
import {RendererEvent} from './utils/renderer-event';
|
||||
@ -370,7 +371,7 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
const component = (
|
||||
<BroadcastCmpt
|
||||
{...theme.getRendererConfig(renderer.name)}
|
||||
{...restSchema}
|
||||
@ -387,6 +388,12 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
|
||||
component={Component}
|
||||
/>
|
||||
);
|
||||
|
||||
return enableAMISDebug ? (
|
||||
<DebugWrapper renderer={renderer}>{component}</DebugWrapper>
|
||||
) : (
|
||||
component
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,8 @@ import {
|
||||
|
||||
import './locale/zh-CN';
|
||||
|
||||
import './utils/debug';
|
||||
|
||||
import animation from './utils/Animation';
|
||||
|
||||
export * from './Schema';
|
||||
|
@ -15,6 +15,7 @@ import {
|
||||
uuid
|
||||
} from './helper';
|
||||
import isPlainObject from 'lodash/isPlainObject';
|
||||
import {debug} from './debug';
|
||||
|
||||
const rSchema = /(?:^|raw\:)(get|post|put|delete|patch|options|head|jsonp):/i;
|
||||
|
||||
@ -265,7 +266,10 @@ export function responseAdaptor(ret: fetcherResult, api: ApiObject) {
|
||||
payload.errors = data.errors;
|
||||
}
|
||||
|
||||
debug('api', 'response', payload);
|
||||
|
||||
if (payload.ok && api.responseData) {
|
||||
debug('api', 'before dataMapping', payload.data);
|
||||
const responseData = dataMapping(
|
||||
api.responseData,
|
||||
|
||||
@ -280,7 +284,7 @@ export function responseAdaptor(ret: fetcherResult, api: ApiObject) {
|
||||
undefined,
|
||||
api.convertKeyToPath
|
||||
);
|
||||
console.debug('responseData', responseData);
|
||||
debug('api', 'after dataMapping', responseData);
|
||||
payload.data = responseData;
|
||||
}
|
||||
|
||||
@ -294,7 +298,11 @@ export function wrapFetcher(
|
||||
return function (api, data, options) {
|
||||
api = buildApi(api, data, options) as ApiObject;
|
||||
|
||||
api.requestAdaptor && (api = api.requestAdaptor(api) || api);
|
||||
if (api.requestAdaptor) {
|
||||
debug('api', 'before requestAdaptor', api);
|
||||
api = api.requestAdaptor(api) || api;
|
||||
debug('api', 'after requestAdaptor', api);
|
||||
}
|
||||
|
||||
if (api.data && (hasFile(api.data) || api.dataType === 'form-data')) {
|
||||
api.data =
|
||||
@ -319,6 +327,8 @@ export function wrapFetcher(
|
||||
api.headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
debug('api', 'request api', api);
|
||||
|
||||
tracker?.(
|
||||
{eventType: 'api', eventData: omit(api, ['config', 'data', 'body'])},
|
||||
api.data
|
||||
@ -355,12 +365,15 @@ export function wrapAdaptor(promise: Promise<fetcherResult>, api: ApiObject) {
|
||||
return adaptor
|
||||
? promise
|
||||
.then(async response => {
|
||||
debug('api', 'before adaptor data', (response as any).data);
|
||||
let result = adaptor((response as any).data, response, api);
|
||||
|
||||
if (result?.then) {
|
||||
result = await result;
|
||||
}
|
||||
|
||||
debug('api', 'after adaptor data', result);
|
||||
|
||||
return {
|
||||
...response,
|
||||
data: result
|
||||
|
438
src/utils/debug.tsx
Normal file
438
src/utils/debug.tsx
Normal file
@ -0,0 +1,438 @@
|
||||
/**
|
||||
* amis 运行时调试功能,为了避免循环引用,这个组件不要依赖 amis 里的组件
|
||||
*/
|
||||
|
||||
import React, {Component, useEffect, useRef, useState} from 'react';
|
||||
import cx from 'classnames';
|
||||
import {findDOMNode, render} from 'react-dom';
|
||||
import JsonView from 'react-json-view';
|
||||
import {autorun, observable} from 'mobx';
|
||||
import {observer} from 'mobx-react';
|
||||
import {uuidv4} from './helper';
|
||||
import position from './position';
|
||||
|
||||
class Log {
|
||||
@observable cat = '';
|
||||
@observable level = '';
|
||||
@observable msg = '';
|
||||
@observable ext? = '';
|
||||
}
|
||||
|
||||
class AMISDebugStore {
|
||||
/**
|
||||
* 当前 tab
|
||||
*/
|
||||
@observable tab: 'log' | 'inspect' = 'log';
|
||||
|
||||
/**
|
||||
* 显示位置,默认在右边
|
||||
*/
|
||||
@observable position: 'left' | 'right' = 'right';
|
||||
|
||||
/**
|
||||
* 组件日志
|
||||
*/
|
||||
@observable logs: Log[] = [];
|
||||
|
||||
/**
|
||||
* Debug 面板是否展开
|
||||
*/
|
||||
@observable isExpanded = false;
|
||||
|
||||
/**
|
||||
* 是否是 inspect 模式,在这个模式下可以查看数据域
|
||||
*/
|
||||
@observable inspectMode = false;
|
||||
|
||||
/**
|
||||
* 当前高亮的组件节点 id
|
||||
*/
|
||||
@observable hoverId: string;
|
||||
|
||||
/**
|
||||
* 当前选中的组件节点 id
|
||||
*/
|
||||
@observable activeId: string;
|
||||
}
|
||||
|
||||
const store = new AMISDebugStore();
|
||||
|
||||
interface ComponentInspect {
|
||||
name: string;
|
||||
component: any;
|
||||
}
|
||||
|
||||
// 存储组件信息用于 debug
|
||||
const ComponentInfo = {} as {[propName: string]: ComponentInspect};
|
||||
|
||||
const LogView = observer(({store}: {store: AMISDebugStore}) => {
|
||||
const logs = store.logs;
|
||||
return (
|
||||
<>
|
||||
{logs.map((log, index) => {
|
||||
return (
|
||||
<div className="AMISDebug-logLine" key={`log-${index}`}>
|
||||
<div className="AMISDebug-logLineMsg">
|
||||
[{log.cat}] {log.msg}
|
||||
</div>
|
||||
{log.ext ? (
|
||||
<JsonView
|
||||
name={null}
|
||||
theme="monokai"
|
||||
src={JSON.parse(log.ext)}
|
||||
collapsed={true}
|
||||
enableClipboard={false}
|
||||
displayDataTypes={false}
|
||||
iconStyle="square"
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
const AMISDebug = observer(({store}: {store: AMISDebugStore}) => {
|
||||
const activeId = store.activeId;
|
||||
const activeComponentInspect = ComponentInfo[activeId];
|
||||
|
||||
// 收集数据域里的数据
|
||||
let start = activeComponentInspect?.component?.props?.data || {};
|
||||
const stacks = [start];
|
||||
|
||||
while (Object.getPrototypeOf(start) !== Object.prototype) {
|
||||
const superData = Object.getPrototypeOf(start);
|
||||
if (Object.prototype.toString.call(superData) !== '[object Object]') {
|
||||
break;
|
||||
}
|
||||
stacks.push(superData);
|
||||
start = superData;
|
||||
}
|
||||
|
||||
const stackDataView = [];
|
||||
if (Object.keys(stacks[0]).length || stacks.length > 1) {
|
||||
let level = 0;
|
||||
for (const stack of stacks) {
|
||||
stackDataView.push(
|
||||
<div key={`data-${level}`}>
|
||||
<h3>Data Level-{level}</h3>
|
||||
<JsonView
|
||||
key={`dataview-${stack}`}
|
||||
name={null}
|
||||
theme="monokai"
|
||||
src={stack}
|
||||
collapsed={level === 0 ? false : true}
|
||||
enableClipboard={false}
|
||||
displayDataTypes={false}
|
||||
iconStyle="square"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
level += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const panelRef = useRef(null);
|
||||
|
||||
const [isResizing, setResizing] = useState(false);
|
||||
|
||||
const [startX, setStartX] = useState(0);
|
||||
|
||||
const [panelWidth, setPanelWidth] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const handleMouseUp = () => {
|
||||
setResizing(false);
|
||||
};
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
if (!isResizing) {
|
||||
return;
|
||||
}
|
||||
const xOffset =
|
||||
store.position === 'right' ? e.clientX - startX : startX - e.clientX;
|
||||
const panel = panelRef.current! as HTMLElement;
|
||||
const targetWidth = Math.max(200, panelWidth - xOffset);
|
||||
panel.style.width = targetWidth + 'px';
|
||||
if (e.stopPropagation) e.stopPropagation();
|
||||
if (e.preventDefault) e.preventDefault();
|
||||
e.cancelBubble = true;
|
||||
return false;
|
||||
};
|
||||
if (isResizing) {
|
||||
document.addEventListener('mousemove', handleMouseMove);
|
||||
document.addEventListener('mouseup', handleMouseUp);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (isResizing) {
|
||||
document.removeEventListener('mousemove', handleMouseMove);
|
||||
document.removeEventListener('mouseup', handleMouseUp);
|
||||
}
|
||||
};
|
||||
}, [isResizing]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx('AMISDebug', {
|
||||
'is-expanded': store.isExpanded,
|
||||
'is-left': store.position === 'left'
|
||||
})}
|
||||
ref={panelRef}
|
||||
>
|
||||
<div
|
||||
className="AMISDebug-toggle"
|
||||
onClick={() => {
|
||||
store.isExpanded = true;
|
||||
}}
|
||||
>
|
||||
{store.isExpanded ? (
|
||||
<i className="fas fa-times"></i>
|
||||
) : (
|
||||
<i className="fas fa-bug"></i>
|
||||
)}
|
||||
</div>
|
||||
<div className={cx('AMISDebug-content')}>
|
||||
<div
|
||||
className="AMISDebug-close"
|
||||
title="Close"
|
||||
onClick={() => {
|
||||
store.isExpanded = false;
|
||||
}}
|
||||
>
|
||||
<i className="fas fa-times" />
|
||||
</div>
|
||||
<div
|
||||
className="AMISDebug-resize"
|
||||
onMouseDown={event => {
|
||||
setStartX(event.clientX);
|
||||
setPanelWidth(
|
||||
parseInt(
|
||||
getComputedStyle(panelRef.current!).getPropertyValue('width'),
|
||||
10
|
||||
)
|
||||
);
|
||||
setResizing(true);
|
||||
}}
|
||||
></div>
|
||||
<div className="AMISDebug-tab">
|
||||
<button
|
||||
className={cx({active: store.tab === 'log'})}
|
||||
onClick={() => {
|
||||
store.tab = 'log';
|
||||
}}
|
||||
>
|
||||
Log
|
||||
</button>
|
||||
<button
|
||||
className={cx({active: store.tab === 'inspect'})}
|
||||
onClick={() => {
|
||||
store.tab = 'inspect';
|
||||
}}
|
||||
>
|
||||
Inspect
|
||||
</button>
|
||||
</div>
|
||||
<div className="AMISDebug-changePosition">
|
||||
{store.position === 'right' ? (
|
||||
<i
|
||||
className="fas fa-chevron-left"
|
||||
title="move to left"
|
||||
onClick={() => {
|
||||
store.position = 'left';
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<i
|
||||
className="fas fa-chevron-right"
|
||||
title="move to right"
|
||||
onClick={() => {
|
||||
store.position = 'right';
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{store.tab === 'log' ? (
|
||||
<div className="AMISDebug-log">
|
||||
<button
|
||||
onClick={() => {
|
||||
store.logs = [];
|
||||
}}
|
||||
>
|
||||
Clear Log
|
||||
</button>
|
||||
<LogView store={store} />
|
||||
</div>
|
||||
) : null}
|
||||
{store.tab === 'inspect' ? (
|
||||
<div className="AMISDebug-inspect">
|
||||
{activeId ? (
|
||||
<>
|
||||
<h3>
|
||||
Component:{' '}
|
||||
<span className="primary">{activeComponentInspect.name}</span>
|
||||
</h3>
|
||||
{stackDataView}
|
||||
</>
|
||||
) : (
|
||||
'Click component to display inspect'
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export let enableAMISDebug = false;
|
||||
|
||||
// 开启 debug 有两种方法,一个是设置 enableAMISDebug 全局变量,另一个是通过 amisDebug=1 query
|
||||
if (
|
||||
(window as any).enableAMISDebug ||
|
||||
location.search.indexOf('amisDebug=1') !== -1
|
||||
) {
|
||||
enableAMISDebug = true;
|
||||
// 页面只有一个
|
||||
if (!(window as any).amisDebugElement) {
|
||||
const amisDebugElement = document.createElement('div');
|
||||
document.body.appendChild(amisDebugElement);
|
||||
const element = <AMISDebug store={store} />;
|
||||
render(element, amisDebugElement);
|
||||
(window as any).amisDebugElement = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 鼠标移动到某个组件的效果
|
||||
*/
|
||||
function handleMouseMove(e: MouseEvent) {
|
||||
if (!store.isExpanded) {
|
||||
return;
|
||||
}
|
||||
const dom = e.target as HTMLElement;
|
||||
const target = dom.closest(`[data-debug-id]`);
|
||||
if (target) {
|
||||
store.hoverId = target.getAttribute('data-debug-id')!;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 点选某个组件
|
||||
*/
|
||||
function handleMouseclick(e: MouseEvent) {
|
||||
if (!store.isExpanded) {
|
||||
return;
|
||||
}
|
||||
const dom = e.target as HTMLElement;
|
||||
const target = dom.closest(`[data-debug-id]`);
|
||||
if (target) {
|
||||
store.activeId = target.getAttribute('data-debug-id')!;
|
||||
store.tab = 'inspect';
|
||||
}
|
||||
}
|
||||
|
||||
// hover 及点击后的高亮
|
||||
const amisHoverBox = document.createElement('div');
|
||||
amisHoverBox.className = 'AMISDebug-hoverBox';
|
||||
const amisActiveBox = document.createElement('div');
|
||||
amisActiveBox.className = 'AMISDebug-activeBox';
|
||||
|
||||
autorun(() => {
|
||||
const hoverId = store.hoverId;
|
||||
const hoverElement = document.querySelector(
|
||||
`[data-debug-id="${hoverId}"]`
|
||||
) as HTMLElement;
|
||||
if (hoverElement) {
|
||||
const offset = position(hoverElement, document.body);
|
||||
amisHoverBox.style.top = `${offset.top}px`;
|
||||
amisHoverBox.style.left = `${offset.left}px`;
|
||||
amisHoverBox.style.width = `${offset.width}px`;
|
||||
amisHoverBox.style.height = `${offset.height}px`;
|
||||
}
|
||||
});
|
||||
|
||||
autorun(() => {
|
||||
const activeId = store.activeId;
|
||||
const activeElement = document.querySelector(
|
||||
`[data-debug-id="${activeId}"]`
|
||||
) as HTMLElement;
|
||||
if (activeElement) {
|
||||
const offset = position(activeElement, document.body);
|
||||
amisActiveBox.style.top = `${offset.top}px`;
|
||||
amisActiveBox.style.left = `${offset.left}px`;
|
||||
amisActiveBox.style.width = `${offset.width}px`;
|
||||
amisActiveBox.style.height = `${offset.height}px`;
|
||||
}
|
||||
});
|
||||
|
||||
if (enableAMISDebug) {
|
||||
document.body.appendChild(amisHoverBox);
|
||||
document.body.appendChild(amisActiveBox);
|
||||
document.addEventListener('mousemove', handleMouseMove);
|
||||
document.addEventListener('click', handleMouseclick);
|
||||
}
|
||||
|
||||
interface DebugWrapperProps {
|
||||
renderer: any;
|
||||
}
|
||||
|
||||
export class DebugWrapper extends Component<DebugWrapperProps> {
|
||||
componentDidMount() {
|
||||
if (!enableAMISDebug) {
|
||||
return;
|
||||
}
|
||||
const root = findDOMNode(this) as HTMLElement;
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
const {renderer} = this.props;
|
||||
const debugId = uuidv4();
|
||||
root.setAttribute('data-debug-id', debugId);
|
||||
ComponentInfo[debugId] = {
|
||||
name: renderer.name,
|
||||
component: this.props.children
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
type Category = 'api' | 'event';
|
||||
|
||||
/**
|
||||
* 一般调试日志
|
||||
* @param msg 简单消息
|
||||
* @param ext 扩展信息
|
||||
*/
|
||||
export function debug(cat: Category, msg: string, ext?: object) {
|
||||
if (!enableAMISDebug) {
|
||||
return;
|
||||
}
|
||||
const log = {
|
||||
cat,
|
||||
level: 'debug',
|
||||
msg: msg,
|
||||
ext: JSON.stringify(ext)
|
||||
};
|
||||
console.debug(log);
|
||||
store.logs.push(log);
|
||||
}
|
||||
|
||||
/**
|
||||
* 警告日志
|
||||
* @param msg 简单消息
|
||||
* @param ext 扩展信息
|
||||
*/
|
||||
export function warning(cat: Category, msg: string, ext?: object) {
|
||||
if (!enableAMISDebug) {
|
||||
return;
|
||||
}
|
||||
store.logs.push({
|
||||
cat,
|
||||
level: 'warn',
|
||||
msg: msg,
|
||||
ext: JSON.stringify(ext)
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user