Skip to content

Commit 11a20b9

Browse files
lazy load comps
1 parent ddf3d0a commit 11a20b9

39 files changed

+1792
-269
lines changed

client/packages/lowcoder/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
"typescript": "^4.8.4",
128128
"vite": "^4.5.2",
129129
"vite-plugin-checker": "^0.5.1",
130+
"vite-plugin-dynamic-import": "^1.5.0",
130131
"vite-plugin-html": "^3.2.0",
131132
"vite-plugin-svgr": "^2.2.2",
132133
"vite-tsconfig-paths": "^3.6.0"

client/packages/lowcoder/src/components/JSLibraryModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import styled from "styled-components";
2-
import React, { ReactNode, useEffect, useState } from "react";
2+
import React, { ReactNode, lazy, useEffect, useState } from "react";
33
import { CustomModal } from "components/CustomModal";
44
import { trans } from "i18n";
55
import { DocLink } from "components/ExternalLink";

client/packages/lowcoder/src/comps/comps/allComp.test.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,15 @@ const COMPS_MAP = {
6363
tableColumnRender: RenderComp,
6464
} as Record<string, CompConstructor>;
6565

66-
Object.entries(uiCompRegistry).forEach(([key, value]) => {
67-
COMPS_MAP["ui_" + key] = value.comp;
68-
});
66+
Object.entries(uiCompRegistry).forEach(async ([key, value]) => {
67+
if(value.lazyLoad) {
68+
const module = await import(`../${value.compPath}`!);
69+
COMPS_MAP["ui_" + key] = module[value.compName!];
70+
} else {
71+
COMPS_MAP["ui_" + key] = value.comp!;
72+
}
73+
})
74+
6975
Object.keys(QueryMap).forEach((key) => {
7076
COMPS_MAP["query_" + key] = (QueryMap as Record<string, CompConstructor>)[key];
7177
});

client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ const onFlyDrop = (layout: Layout, items: Layout, dispatch: DispatchType) => {
195195
}
196196
};
197197

198-
const onDrop = (
198+
const onDrop = async (
199199
layout: Layout,
200200
items: Layout,
201201
event: DragEvent<HTMLElement>,
@@ -222,7 +222,17 @@ const onDrop = (
222222
const nameGenerator = editorState.getNameGenerator();
223223
const compInfo = parseCompType(compType);
224224
const compName = nameGenerator.genItemName(compInfo.compName);
225-
const defaultDataFn = uiCompRegistry[compType as UICompType]?.defaultDataFn;
225+
const {
226+
defaultDataFnName,
227+
defaultDataFnPath,
228+
} = uiCompRegistry[compType as UICompType];
229+
230+
let defaultDataFn = undefined;
231+
if(defaultDataFnName && defaultDataFnPath) {
232+
const module = await import(`../../${defaultDataFnPath}.tsx`);
233+
defaultDataFn = module[defaultDataFnName];
234+
}
235+
226236
const widgetValue: GridItemDataType = {
227237
compType,
228238
name: compName,

client/packages/lowcoder/src/comps/comps/fileComp/fileComp.test.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { readFile } from "fs/promises";
1+
// import { readFile } from "fs/promises";
22
import { resolveParsedValue } from "./fileComp";
33
import mime from "mime";
4+
const { readFile } = require("node:fs/promises");
45

56
global.TextDecoder = require("util").TextDecoder;
67

@@ -90,7 +91,7 @@ function toArrayBuffer(buf: Buffer) {
9091
}
9192

9293
function getFile(path: string) {
93-
return readFile(path).then((b) => ({
94+
return readFile(path).then((b: Buffer) => ({
9495
originFileObj: {
9596
arrayBuffer: () => new Promise((resolve) => resolve(toArrayBuffer(b))),
9697
type: mime.getType(path.substring(path.lastIndexOf("."))),

client/packages/lowcoder/src/comps/comps/gridItemComp.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { profilerCallback } from "util/cacheUtils";
2323
import { setFieldsNoTypeCheck, shallowEqual } from "util/objectUtils";
2424
import { remoteComp } from "./remoteComp/remoteComp";
2525
import { SimpleNameComp } from "./simpleNameComp";
26+
import { lazyLoadComp } from "./lazyLoadComp/lazyLoadComp";
2627

2728
export function defaultLayout(compType: UICompType): UICompLayoutInfo {
2829
return uiCompRegistry[compType]?.layoutInfo ?? { w: 5, h: 5 };
@@ -38,6 +39,7 @@ const TmpComp = withTypeAndChildren<
3839
>(
3940
(type) => {
4041
const compInfo = parseCompType(type);
42+
4143
if (compInfo.isRemote) {
4244
return remoteComp(compInfo);
4345
}
@@ -46,8 +48,15 @@ const TmpComp = withTypeAndChildren<
4648
if (name !== type) {
4749
continue;
4850
}
49-
const comp = manifest.withoutLoading ? manifest.comp : withIsLoading(manifest.comp);
50-
return withErrorBoundary(comp) as ExposingMultiCompConstructor;
51+
52+
if(manifest.lazyLoad) {
53+
return lazyLoadComp(
54+
manifest.compName,
55+
manifest.compPath,
56+
);
57+
}
58+
const comp = manifest.withoutLoading ? manifest.comp : withIsLoading(manifest.comp!);
59+
return withErrorBoundary(comp!) as ExposingMultiCompConstructor;
5160
}
5261
},
5362
"button",

client/packages/lowcoder/src/comps/comps/jsonSchemaFormComp/dateWidget.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { WidgetProps } from "@rjsf/utils";
1+
import type { WidgetProps } from "@rjsf/utils";
22
import { default as DatePicker } from "antd/es/date-picker";
33
import dayjs from "dayjs";
44

client/packages/lowcoder/src/comps/comps/jsonSchemaFormComp/jsonSchemaFormComp.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { withTheme } from '@rjsf/core';
2-
import { RJSFValidationError, ErrorListProps, UISchemaSubmitButtonOptions } from "@rjsf/utils";
2+
import type { RJSFValidationError, ErrorListProps, UISchemaSubmitButtonOptions } from "@rjsf/utils";
33
import validator from "@rjsf/validator-ajv8";
44
// import Ajv from "@rjsf/validator-ajv8";
55
import { default as Button } from "antd/es/button";
@@ -10,9 +10,8 @@ import { JsonSchemaFormStyle, JsonSchemaFormStyleType } from "comps/controls/sty
1010
import { depsConfig, NameConfigHidden, withExposingConfigs } from "comps/generators/withExposing";
1111
import { withMethodExposing } from "comps/generators/withMethodExposing";
1212
import { ValueFromOption } from "lowcoder-design";
13-
import { i18n } from "lowcoder-core";
1413
import { i18nObjs, trans } from "i18n";
15-
import { JSONSchema7 } from "json-schema";
14+
import type { JSONSchema7 } from "json-schema";
1615
import styled from "styled-components";
1716
import { toBoolean, toNumber, toString } from "util/convertUtils";
1817
import { Section, sectionNames } from "lowcoder-design";
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { ExecuteAction } from "comps/controls/actionSelector/executeCompTypes";
2+
import { simpleMultiComp, valueComp } from "comps/generators";
3+
import { withSimpleExposing } from "comps/generators/withExposing";
4+
import { withMethodExposing } from "comps/generators/withMethodExposing";
5+
import { evalAndReduce } from "comps/utils";
6+
import { customAction } from "lowcoder-core";
7+
import { lazyLoadComp } from "./lazyLoadComp";
8+
9+
const TestComp = valueComp<number>(123);
10+
export { TestComp };
11+
12+
const compName = 'TestComp';
13+
const compPath = 'comps/lazyLoadComp/lazyLoadComp.test';
14+
15+
const RComp = lazyLoadComp(compName, compPath);
16+
17+
test("lazyload comp", async () => {
18+
let c: any = null;
19+
c = new RComp({
20+
dispatch: (action) => {
21+
if (c) {
22+
c = c.reduce(action);
23+
}
24+
},
25+
});
26+
27+
expect(c.toJsonValue()).toBe(undefined);
28+
await c.load();
29+
expect(c.toJsonValue()).toBe(123);
30+
31+
c.dispatchChangeValueAction(345);
32+
expect(c.toJsonValue()).toBe(345);
33+
});
34+
35+
test("lazyload comp keep values", async () => {
36+
let c: any = null;
37+
c = new RComp({
38+
dispatch: (action) => {
39+
if (c) {
40+
c = c.reduce(action);
41+
}
42+
},
43+
value: 456,
44+
});
45+
46+
expect(c.toJsonValue()).toBe(456);
47+
await c.load();
48+
expect(c.toJsonValue()).toBe(456);
49+
});
50+
51+
test("lazyload comp exposing data", async () => {
52+
const EComp = lazyLoadComp(compName, compPath, async () => {
53+
return withSimpleExposing(simpleMultiComp({ hello: valueComp(123) }), (comp) => {
54+
return {
55+
hello: comp.children.hello.getView(),
56+
};
57+
});
58+
});
59+
60+
let c: any = null;
61+
c = new EComp({
62+
dispatch: (action) => {
63+
if (c) {
64+
c = c.reduce(action);
65+
}
66+
},
67+
});
68+
69+
await c.load();
70+
const c1 = evalAndReduce(c);
71+
expect(c1.exposingValues.hello).toBe(123);
72+
});
73+
74+
test("lazyload comp execute method", async () => {
75+
const MComp = lazyLoadComp(compName, compPath, async () => {
76+
return withMethodExposing(simpleMultiComp({ hello: valueComp<number>(123) }), [
77+
{
78+
method: {
79+
name: "add",
80+
params: [{ name: "value", type: "number" }],
81+
},
82+
execute: (comp, values) => {
83+
const hello = comp.children.hello;
84+
hello.dispatchChangeValueAction(hello.getView() + (values[0] as number));
85+
},
86+
},
87+
]);
88+
});
89+
let c: any = null;
90+
c = new MComp({
91+
dispatch: (action) => {
92+
if (c) {
93+
c = c.reduce(action);
94+
}
95+
},
96+
});
97+
98+
await c.load();
99+
c.reduce(
100+
customAction<ExecuteAction>(
101+
{
102+
type: "execute",
103+
methodName: "add",
104+
params: [10],
105+
},
106+
false
107+
)
108+
);
109+
await new Promise((r) => setTimeout(r, 20));
110+
expect(c.children.hello.getView()).toEqual(133);
111+
});

0 commit comments

Comments
 (0)