From 55dac3b56baa13b8b66de746d2af5a2bd3b5c065 Mon Sep 17 00:00:00 2001 From: * <8> Date: Mon, 21 Mar 2022 17:50:18 +0800 Subject: [PATCH 1/3] Match-id-580af01343fa5bba627a04ab667a638ec280a603 --- libs/horizon/src/renderer/components/BaseClassComponent.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/horizon/src/renderer/components/BaseClassComponent.ts b/libs/horizon/src/renderer/components/BaseClassComponent.ts index 74f6df80..b5b202c2 100644 --- a/libs/horizon/src/renderer/components/BaseClassComponent.ts +++ b/libs/horizon/src/renderer/components/BaseClassComponent.ts @@ -1,18 +1,22 @@ /** * Component的api setState和forceUpdate在实例生成阶段实现 */ + class Component
{ props: P; context: C; state: S | null; refs: any; - setState: any; forceUpdate: any; constructor(props: P, context: C) { this.props = props; this.context = context; } + + setState(state: S) { + console.error('Cant not call `this.setState` in the constructor of class component, it will do nothing') + } } // 兼容三方件 react-lifecycles-compat,它会读取 isReactComponent 属性值,不添加会导致 eview-ui 官网白屏 From ea44e30933164f272d7411e6d6b637d220a9083c Mon Sep 17 00:00:00 2001 From: * <8> Date: Tue, 22 Mar 2022 10:26:15 +0800 Subject: [PATCH 2/3] Match-id-5935bd5d4b80a4524d2b9a839ca106c4249ad3e5 --- .eslintignore | 1 + .eslintrc.js | 5 +++++ libs/horizon/index.d.ts | 5 ++++- libs/horizon/src/renderer/components/BaseClassComponent.ts | 7 +++++-- tsconfig.json | 4 ++-- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.eslintignore b/.eslintignore index 25439044..60feb237 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ **/node_modules build/ +*.d.ts diff --git a/.eslintrc.js b/.eslintrc.js index 79557bf5..46239631 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,8 @@ module.exports = { extends: [ 'eslint:recommended', + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", 'prettier', ], root: true, @@ -41,6 +43,9 @@ module.exports = { 'no-for-of-loops/no-for-of-loops': 'error', 'no-function-declare-after-return/no-function-declare-after-return': 'error', }, + globals: { + isDev: true + }, overrides: [ { files: [ diff --git a/libs/horizon/index.d.ts b/libs/horizon/index.d.ts index 4c54c7c5..bab6684d 100644 --- a/libs/horizon/index.d.ts +++ b/libs/horizon/index.d.ts @@ -1 +1,4 @@ -declare var isDev: any; +/* + 区分是否开发者模式 + */ +declare var isDev: boolean; diff --git a/libs/horizon/src/renderer/components/BaseClassComponent.ts b/libs/horizon/src/renderer/components/BaseClassComponent.ts index b5b202c2..c8fcf9a9 100644 --- a/libs/horizon/src/renderer/components/BaseClassComponent.ts +++ b/libs/horizon/src/renderer/components/BaseClassComponent.ts @@ -2,7 +2,7 @@ * Component的api setState和forceUpdate在实例生成阶段实现 */ -class Component
{ +class Component
{ props: P; context: C; state: S | null; @@ -15,12 +15,15 @@ class Component
{
}
setState(state: S) {
- console.error('Cant not call `this.setState` in the constructor of class component, it will do nothing')
+ if (isDev) {
+ console.error('Cant not call `this.setState` in the constructor of class component, it will do nothing');
+ }
}
}
// 兼容三方件 react-lifecycles-compat,它会读取 isReactComponent 属性值,不添加会导致 eview-ui 官网白屏
Component.prototype.isReactComponent = true;
+
/**
* 支持PureComponent
*/
diff --git a/tsconfig.json b/tsconfig.json
index e05c4501..e85c8cac 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -34,8 +34,8 @@
},
"include": [
"./libs/**/src/**/*.ts",
- "libs/index.d.ts"
+ "libs/horizon/index.d.ts"
],
"exclude": ["node_modules", "**/*.spec.ts", "dev"],
- "types": ["node"],
+ "types": ["node"]
}
From dfa9ad8f020bfedba20ee8c351ee27773135ec09 Mon Sep 17 00:00:00 2001
From: * <8>
Date: Wed, 23 Mar 2022 10:15:58 +0800
Subject: [PATCH 3/3] Match-id-2c5b3e4e34c044c80842fd08377d49c00014c684
---
libs/horizon/src/renderer/TreeBuilder.ts | 33 +++++++------------
.../renderer/components/BaseClassComponent.ts | 2 +-
.../src/renderer/diff/nodeDiffComparator.ts | 10 +++---
.../src/renderer/render/MemoComponent.ts | 7 ++--
.../src/renderer/render/SuspenseComponent.ts | 5 +--
libs/horizon/src/renderer/utils/vNodePath.ts | 15 +++++++++
.../src/renderer/vnode/VNodeCreator.ts | 9 ++---
7 files changed, 46 insertions(+), 35 deletions(-)
create mode 100644 libs/horizon/src/renderer/utils/vNodePath.ts
diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts
index 9bf2455a..721bbff6 100644
--- a/libs/horizon/src/renderer/TreeBuilder.ts
+++ b/libs/horizon/src/renderer/TreeBuilder.ts
@@ -35,6 +35,7 @@ import {
updateParentsChildShouldUpdate,
updateShouldUpdateOfTree
} from './vnode/VNodeShouldUpdate';
+import { getPathArr } from './utils/vNodePath';
// 不可恢复错误
let unrecoverableErrorDuringBuild: any = null;
@@ -142,11 +143,11 @@ function handleError(root, error): void {
}
// 判断数组中节点的path的idx元素是否都相等
-function isEqualByIndex(idx: number, nodes: Array {
props: P;
context: C;
state: S | null;
refs: any;
forceUpdate: any;
+ isReactComponent: boolean;
constructor(props: P, context: C) {
this.props = props;
diff --git a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
index db920f79..2b97612f 100644
--- a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
+++ b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
@@ -17,6 +17,7 @@ import {
isObjectType,
} from './DiffTools';
import { travelChildren } from '../vnode/VNodeUtils';
+import { markVNodePath } from '../utils/vNodePath';
enum DiffCategory {
TEXT_NODE = 'TEXT_NODE',
@@ -241,7 +242,7 @@ function diffArrayNodesHandler(
prevNewNode.next = newNode;
newNode.cIndex = prevNewNode.cIndex + 1;
}
- newNode.path = newNode.parent.path + newNode.cIndex;
+ markVNodePath(newNode);
prevNewNode = newNode;
}
@@ -477,7 +478,7 @@ function setVNodesCIndex(startChild: VNode | null, startIdx: number) {
while (node !== null) {
node.cIndex = idx;
- node.path = node.parent.path + node.cIndex;
+ markVNodePath(node);
node = node.next;
idx++;
}
@@ -528,7 +529,7 @@ function diffStringNodeHandler(
}
newTextNode.parent = parentNode;
newTextNode.cIndex = 0;
- newTextNode.path = newTextNode.parent.path + newTextNode.cIndex;
+ markVNodePath(newTextNode);
return newTextNode;
}
@@ -606,7 +607,8 @@ function diffObjectNodeHandler(
resultNode.parent = parentNode;
resultNode.cIndex = 0;
- resultNode.path = resultNode.parent.path + resultNode.cIndex;
+ markVNodePath(resultNode);
+
if (startDelVNode) {
deleteVNodes(parentNode, startDelVNode);
}
diff --git a/libs/horizon/src/renderer/render/MemoComponent.ts b/libs/horizon/src/renderer/render/MemoComponent.ts
index 84daa883..99a34364 100644
--- a/libs/horizon/src/renderer/render/MemoComponent.ts
+++ b/libs/horizon/src/renderer/render/MemoComponent.ts
@@ -8,6 +8,7 @@ import {
TYPE_PROFILER,
TYPE_STRICT_MODE,
} from '../../external/JSXElementType';
+import { markVNodePath } from '../utils/vNodePath';
export function bubbleRender() {}
@@ -20,7 +21,7 @@ export function captureMemoComponent(
const newProps = mergeDefaultProps(Component, processing.props);
if (processing.isCreated) {
- let newChild = null;
+ let newChild: VNode | null = null;
const type = Component.type;
if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) {
newChild = createFragmentVNode(null, newProps.children);
@@ -29,7 +30,7 @@ export function captureMemoComponent(
}
newChild.parent = processing;
newChild.ref = processing.ref;
- newChild.path = newChild.parent.path + newChild.cIndex;
+ markVNodePath(newChild);
processing.child = newChild;
return newChild;
@@ -48,7 +49,7 @@ export function captureMemoComponent(
const newChild = updateVNode(firstChild, newProps);
newChild.parent = processing;
newChild.cIndex = 0;
- newChild.path = newChild.parent.path + newChild.cIndex;
+ markVNodePath(newChild);
newChild.ref = processing.ref;
processing.child = newChild;
diff --git a/libs/horizon/src/renderer/render/SuspenseComponent.ts b/libs/horizon/src/renderer/render/SuspenseComponent.ts
index cdc2f4a4..3e7bdcb2 100644
--- a/libs/horizon/src/renderer/render/SuspenseComponent.ts
+++ b/libs/horizon/src/renderer/render/SuspenseComponent.ts
@@ -11,6 +11,7 @@ import {pushForceUpdate} from '../UpdateHandler';
import {launchUpdateFromVNode, tryRenderFromRoot} from '../TreeBuilder';
import {updateShouldUpdateOfTree} from '../vnode/VNodeShouldUpdate';
import {getContextChangeCtx} from '../ContextSaver';
+import { markVNodePath } from '../utils/vNodePath';
export enum SuspenseChildStatus {
Init = '',
@@ -44,7 +45,7 @@ function createFallback(processing: VNode, fallbackChildren) {
fallbackFragment.parent = processing;
fallbackFragment.eIndex = 1;
fallbackFragment.cIndex = 1;
- fallbackFragment.path = fallbackFragment.parent.path + fallbackFragment.cIndex;
+ markVNodePath(fallbackFragment);
processing.suspenseChildStatus = SuspenseChildStatus.ShowFallback;
return fallbackFragment;
@@ -76,7 +77,7 @@ function createSuspenseChildren(processing: VNode, newChildren) {
childFragment.parent = processing;
childFragment.cIndex = 0;
- childFragment.path = childFragment.parent.path + childFragment.cIndex;
+ markVNodePath(childFragment);
processing.child = childFragment;
processing.promiseResolve = false;
return processing.child;
diff --git a/libs/horizon/src/renderer/utils/vNodePath.ts b/libs/horizon/src/renderer/utils/vNodePath.ts
new file mode 100644
index 00000000..5f8b78ac
--- /dev/null
+++ b/libs/horizon/src/renderer/utils/vNodePath.ts
@@ -0,0 +1,15 @@
+import { VNode } from '../vnode/VNode';
+
+const PATH_DELIMITER = ',';
+
+/**
+ * 标记VNode在VNode树中的路径
+ * @param vNode
+ */
+export function markVNodePath(vNode: VNode) {
+ vNode.path = `${vNode.parent!.path}${PATH_DELIMITER}${vNode.cIndex}`;
+}
+
+export function getPathArr(vNode: VNode) {
+ return vNode.path.split(PATH_DELIMITER);
+}
diff --git a/libs/horizon/src/renderer/vnode/VNodeCreator.ts b/libs/horizon/src/renderer/vnode/VNodeCreator.ts
index 865f791e..8c76d63c 100644
--- a/libs/horizon/src/renderer/vnode/VNodeCreator.ts
+++ b/libs/horizon/src/renderer/vnode/VNodeCreator.ts
@@ -26,6 +26,7 @@ import {
} from '../../external/JSXElementType';
import { VNode } from './VNode';
import { JSXElement } from '../Types';
+import { markVNodePath } from '../utils/vNodePath';
const typeLazyMap = {
[TYPE_FORWARD_REF]: ForwardRef,
@@ -135,7 +136,7 @@ export function createUndeterminedVNode(type, key, props) {
export function createTreeRootVNode(container) {
const vNode = newVirtualNode(TreeRoot, null, null, container);
- vNode.path += 0;
+ vNode.path = '0';
vNode.updates = [];
return vNode;
}
@@ -147,7 +148,7 @@ export function createVNode(tag: VNodeTag | string, ...secondArg) {
case TreeRoot:
// 创建treeRoot
vNode = newVirtualNode(TreeRoot, null, null, secondArg[0]);
- vNode.path += 0;
+ vNode.path = '0';
vNode.updates = [];
break;
@@ -178,7 +179,7 @@ export function onlyUpdateChildVNodes(processing: VNode): VNode | null {
let child: VNode | null = processing.child;
while (child !== null) {
updateVNode(child, child.props);
- child.path = child.parent.path + child.cIndex;
+ markVNodePath(child);
child = child.next;
}
}
@@ -209,7 +210,7 @@ export function onlyUpdateChildVNodes(processing: VNode): VNode | null {
while (queue.length) {
const vNode = queue.shift()!;
- vNode.path = vNode.parent.path + vNode.cIndex;
+ markVNodePath(vNode);
putChildrenIntoQueue(vNode)
}