Skip to content
This repository was archived by the owner on Nov 19, 2025. It is now read-only.

Commit a31dc87

Browse files
authored
refactor(hub-common): remove dynamic imports (#2050)
1 parent 8e25a27 commit a31dc87

File tree

15 files changed

+272
-323
lines changed

15 files changed

+272
-323
lines changed

.changeset/short-horses-march.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@esri/hub-common": patch
3+
---
4+
5+
removes dynamic imports from modules

.eslintrc.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ module.exports = {
5353
message:
5454
"Enums are not allowed. Consider using separate const and type. E.g. const FRUIT = { APPLE: 'apple', BANANA: 'banana' } as const; type Fruit = typeof FRUIT[keyof typeof FRUIT];",
5555
},
56+
{
57+
selector: 'ImportExpression',
58+
message: 'Dynamic import() is not allowed.',
59+
},
5660
],
5761
"@typescript-eslint/no-require-imports": "error",
5862
},

packages/common/src/channels/HubChannel.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ import {
1111
IConvertToCardModelOpts,
1212
IHubCardViewModel,
1313
} from "../core/types/IHubCardViewModel";
14+
import { fetchHubChannel } from "./fetch";
15+
import { createHubChannel, deleteHubChannel, updateHubChannel } from "./edit";
16+
import { getEditorConfig } from "../core/schemas/getEditorConfig";
17+
import { transformEntityToEditor } from "./_internal/transformEntityToEditor";
18+
import { transformEditorToEntity } from "./_internal/transformEditorToEntity";
1419

1520
export class HubChannel
1621
implements IWithStoreBehavior<IHubChannel>, IWithEditorBehavior
@@ -69,7 +74,6 @@ export class HubChannel
6974
context: IArcGISContext
7075
): Promise<HubChannel> {
7176
try {
72-
const { fetchHubChannel } = await import("./fetch");
7377
const entity = await fetchHubChannel(identifier, context);
7478
return HubChannel.fromJson(entity, context);
7579
} catch (e) {
@@ -151,10 +155,8 @@ export class HubChannel
151155
}
152156

153157
if (this.entity.id) {
154-
const { updateHubChannel } = await import("./edit");
155158
this.entity = await updateHubChannel(this.entity, this.context);
156159
} else {
157-
const { createHubChannel } = await import("./edit");
158160
this.entity = await createHubChannel(this.entity, this.context);
159161
}
160162
}
@@ -168,7 +170,6 @@ export class HubChannel
168170
if (this.isDestroyed) {
169171
throw new Error("HubChannel is already destroyed.");
170172
}
171-
const { deleteHubChannel } = await import("./edit");
172173
this.isDestroyed = true;
173174
await deleteHubChannel(this.entity.id, this.context);
174175
}
@@ -193,7 +194,6 @@ export class HubChannel
193194
i18nScope: string,
194195
type: ChannelEditorType
195196
): Promise<IEditorConfig> {
196-
const { getEditorConfig } = await import("../core/schemas/getEditorConfig");
197197
return getEditorConfig(i18nScope, type, this.entity, this.context);
198198
}
199199

@@ -207,10 +207,7 @@ export class HubChannel
207207
_editorContext: IEntityEditorContext,
208208
_include?: string[]
209209
): Promise<IHubChannelEditor> {
210-
const { transformEntityToEditor } = await import(
211-
"./_internal/transformEntityToEditor"
212-
);
213-
return transformEntityToEditor(this.entity, this.context);
210+
return Promise.resolve(transformEntityToEditor(this.entity, this.context));
214211
}
215212

216213
/**
@@ -219,9 +216,6 @@ export class HubChannel
219216
* @returns a promise that resolves an IHubChannel
220217
*/
221218
async fromEditor(editor: IHubChannelEditor): Promise<IHubChannel> {
222-
const { transformEditorToEntity } = await import(
223-
"./_internal/transformEditorToEntity"
224-
);
225219
this.entity = {
226220
...this.entity,
227221
...transformEditorToEntity(editor),

packages/common/src/content/HubContent.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ import { IWithStoreBehavior } from "../core/behaviors/IWithStoreBehavior";
1010
import { getEditorConfig } from "../core/schemas/getEditorConfig";
1111
import { IEntityEditorContext } from "../core/types/HubEntityEditor";
1212
import { cloneObject } from "../util";
13-
import { editorToContent } from "./edit";
13+
import {
14+
createContent,
15+
deleteContent,
16+
editorToContent,
17+
updateContent,
18+
} from "./edit";
1419
import { ContentEditorType } from "./_internal/contentEditorTypes";
1520
import { enrichEntity } from "../core/enrichEntity";
1621
import { shouldShowDownloadsConfiguration } from "./_internal/shouldShowDownloadsConfiguration";
@@ -46,8 +51,6 @@ export class HubContent
4651
*/
4752
async save(): Promise<void> {
4853
this._checkDestroyed();
49-
const { createContent, updateContent } = await import("./edit");
50-
5154
if (this.entity.id) {
5255
// update it
5356
this.entity = await updateContent(
@@ -85,7 +88,6 @@ export class HubContent
8588
async delete(): Promise<void> {
8689
this._checkDestroyed();
8790
this.isDestroyed = true;
88-
const { deleteContent } = await import("./edit");
8991
// Delegate to module fn
9092
await deleteContent(this.entity.id, this.context.hubRequestOptions);
9193
}

packages/common/src/core/schemas/internal/follow/FollowCardUiSchema.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ export const buildUiSchema = (
3232
i18nScope: string,
3333
config: FollowCardEditorOptions,
3434
context: IArcGISContext
35-
): IUiSchema => {
36-
return {
35+
): Promise<IUiSchema> => {
36+
return Promise.resolve({
3737
type: "Layout",
3838
elements: [
3939
{
@@ -133,7 +133,7 @@ export const buildUiSchema = (
133133
],
134134
},
135135
],
136-
};
136+
});
137137
};
138138

139139
const HIDE_FOR_NO_ENTITY_ID = {

packages/common/src/core/schemas/internal/getCardEditorSchemas.ts

Lines changed: 35 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ import {
1616
import { cloneObject } from "../../../util";
1717
import type { IArcGISContext } from "../../../types/IArcGISContext";
1818
import { ICardEditorModuleType } from "../types";
19+
import { MetricSchema } from "./metrics/MetricSchema";
20+
import { FollowSchema } from "./follow/FollowSchema";
21+
import { EmbedCardSchema } from "./embed/EmbedSchema";
22+
import { EventGalleryCardSchema } from "./events/EventGalleryCardSchema";
23+
import * as buildStatUiSchema from "./metrics/StatCardUiSchema";
24+
import * as buildFollowUiSchema from "./follow/FollowCardUiSchema";
25+
import * as buildEmbedSchema from "./embed/EmbedUiSchema";
26+
import * as buildEventGalleryCardSchema from "./events/EventGalleryCardUiSchema";
1927

2028
/**
2129
* get the editor schema and uiSchema defined for a layout card.
@@ -35,85 +43,48 @@ export async function getCardEditorSchemas(
3543
context: IArcGISContext
3644
): Promise<IEditorConfig> {
3745
const cardType = getCardType(type);
38-
39-
// schema and uiSchema are dynamically imported based
40-
// on the previous editor types
41-
4246
let schema;
4347
let uiSchema;
44-
let schemaPromise;
45-
let uiSchemaPromise;
46-
// defaults is used below... but maybe in a closure?
47-
// tslint:disable-next-line:no-unused-variable
4848
let defaults;
4949

5050
switch (cardType) {
5151
case "stat": {
52-
// get correct module
53-
schemaPromise = import("./metrics/MetricSchema");
54-
uiSchemaPromise = {
55-
"hub:card:stat": (): Promise<
56-
typeof import("./metrics/StatCardUiSchema")
57-
> => import("./metrics/StatCardUiSchema"),
58-
}[type as StatCardEditorType];
59-
60-
// Allow imports to run in parallel
61-
await Promise.all([schemaPromise, uiSchemaPromise()]).then(
62-
async ([schemaModuleResolved, uiSchemaModuleResolved]) => {
63-
const { MetricSchema } = schemaModuleResolved;
64-
schema = cloneObject(MetricSchema);
65-
uiSchema = await uiSchemaModuleResolved.buildUiSchema(
66-
i18nScope,
67-
options as StatCardEditorOptions,
68-
context
69-
);
70-
71-
// if we have buildDefaults, build the defaults
72-
// TODO: when first implementing buildDefaults for initiative templates, remove the ignore line
73-
74-
/* istanbul ignore next */
75-
if ((uiSchemaModuleResolved as ICardEditorModuleType).buildDefaults) {
76-
defaults = (
77-
uiSchemaModuleResolved as ICardEditorModuleType
78-
).buildDefaults(i18nScope, options, context);
79-
}
80-
}
52+
const MODULES: Record<StatCardEditorType, ICardEditorModuleType> = {
53+
"hub:card:stat": buildStatUiSchema,
54+
} as Record<StatCardEditorType, ICardEditorModuleType>;
55+
const module = MODULES[type as StatCardEditorType];
56+
schema = cloneObject(MetricSchema);
57+
uiSchema = await module.buildUiSchema(
58+
i18nScope,
59+
options as StatCardEditorOptions,
60+
context
8161
);
62+
// if we have buildDefaults, build the defaults
63+
// TODO: when first implementing buildDefaults for initiative templates, remove the ignore line
64+
65+
/* istanbul ignore next */
66+
if (module.buildDefaults) {
67+
defaults = module.buildDefaults(i18nScope, options, context);
68+
}
8269

8370
break;
8471
}
8572
case "follow": {
86-
// get correct module
87-
schemaPromise = import("./follow/FollowSchema");
88-
uiSchemaPromise = {
89-
"hub:card:follow": (): Promise<
90-
typeof import("./follow/FollowCardUiSchema")
91-
> => import("./follow/FollowCardUiSchema"),
92-
}[type as FollowCardEditorType];
93-
94-
// Allow imports to run in parallel
95-
await Promise.all([schemaPromise, uiSchemaPromise()]).then(
96-
([schemaModuleResolved, uiSchemaModuleResolved]) => {
97-
const { FollowSchema: FollowSchema } = schemaModuleResolved;
98-
schema = cloneObject(FollowSchema);
99-
uiSchema = uiSchemaModuleResolved.buildUiSchema(
100-
i18nScope,
101-
options as FollowCardEditorOptions,
102-
context
103-
);
104-
}
73+
const MODULES: Record<FollowCardEditorType, ICardEditorModuleType> = {
74+
"hub:card:follow": buildFollowUiSchema,
75+
} as Record<FollowCardEditorType, ICardEditorModuleType>;
76+
const module = MODULES[type as FollowCardEditorType];
77+
schema = cloneObject(FollowSchema);
78+
uiSchema = await module.buildUiSchema(
79+
i18nScope,
80+
options as FollowCardEditorOptions,
81+
context
10582
);
10683
break;
10784
}
10885
case "embed": {
109-
schemaPromise = import("./embed/EmbedSchema");
110-
uiSchemaPromise = import("./embed/EmbedUiSchema");
111-
const [{ EmbedCardSchema }, { buildUiSchema }] = await Promise.all([
112-
schemaPromise,
113-
uiSchemaPromise,
114-
]);
11586
schema = cloneObject(EmbedCardSchema);
116-
uiSchema = buildUiSchema(
87+
uiSchema = buildEmbedSchema.buildUiSchema(
11788
i18nScope,
11889
options as EmbedCardEditorOptions,
11990
context
@@ -122,13 +93,8 @@ export async function getCardEditorSchemas(
12293
break;
12394
}
12495
case "eventGallery": {
125-
schemaPromise = import("./events/EventGalleryCardSchema");
126-
uiSchemaPromise = import("./events/EventGalleryCardUiSchema");
127-
const [{ EventGalleryCardSchema }, { buildUiSchema }] = await Promise.all(
128-
[schemaPromise, uiSchemaPromise]
129-
);
13096
schema = cloneObject(EventGalleryCardSchema);
131-
uiSchema = await buildUiSchema(
97+
uiSchema = await buildEventGalleryCardSchema.buildUiSchema(
13298
i18nScope,
13399
options as EventGalleryCardEditorOptions,
134100
context

0 commit comments

Comments
 (0)