Skip to content

Commit eafadf7

Browse files
clydinalan-agius4
authored andcommitted
refactor(@angular-devkit/build-angular): cache compiled load ESM file helper
The dynamically compiled ESM import helper is now cached to prevent the need to recompile the helper function everytime a load ESM helper call is made. This helper is currently used to workaround dynamic import limitations with the TypeScript compilation output. Once the build process is updated, it will no longer be required. (cherry picked from commit 6d8d948)
1 parent ee0991b commit eafadf7

File tree

4 files changed

+45
-5
lines changed

4 files changed

+45
-5
lines changed

packages/angular/cli/src/utilities/load-esm.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
/**
10+
* Lazily compiled dynamic import loader function.
11+
*/
12+
let load: (<T>(modulePath: string | URL) => Promise<T>) | undefined;
13+
914
/**
1015
* This uses a dynamic import to load a module which may be ESM.
1116
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
@@ -19,5 +24,10 @@
1924
* @returns A Promise that resolves to the dynamically imported module.
2025
*/
2126
export function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
22-
return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise<T>;
27+
load ??= new Function('modulePath', `return import(modulePath);`) as Exclude<
28+
typeof load,
29+
undefined
30+
>;
31+
32+
return load(modulePath);
2333
}

packages/angular_devkit/architect/node/node-modules-architect-host.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@ export class WorkspaceNodeModulesArchitectHost implements ArchitectHost<NodeModu
213213
}
214214
}
215215

216+
/**
217+
* Lazily compiled dynamic import loader function.
218+
*/
219+
let load: (<T>(modulePath: string | URL) => Promise<T>) | undefined;
220+
216221
/**
217222
* This uses a dynamic import to load a module which may be ESM.
218223
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
@@ -225,8 +230,13 @@ export class WorkspaceNodeModulesArchitectHost implements ArchitectHost<NodeModu
225230
* @param modulePath The path of the module to load.
226231
* @returns A Promise that resolves to the dynamically imported module.
227232
*/
228-
function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
229-
return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise<T>;
233+
export function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
234+
load ??= new Function('modulePath', `return import(modulePath);`) as Exclude<
235+
typeof load,
236+
undefined
237+
>;
238+
239+
return load(modulePath);
230240
}
231241

232242
// eslint-disable-next-line @typescript-eslint/no-explicit-any

packages/angular_devkit/build_angular/src/utils/load-esm.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
/**
10+
* Lazily compiled dynamic import loader function.
11+
*/
12+
let load: (<T>(modulePath: string | URL) => Promise<T>) | undefined;
13+
914
/**
1015
* This uses a dynamic import to load a module which may be ESM.
1116
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
@@ -19,5 +24,10 @@
1924
* @returns A Promise that resolves to the dynamically imported module.
2025
*/
2126
export function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
22-
return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise<T>;
27+
load ??= new Function('modulePath', `return import(modulePath);`) as Exclude<
28+
typeof load,
29+
undefined
30+
>;
31+
32+
return load(modulePath);
2333
}

packages/angular_devkit/schematics_cli/bin/schematics.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,11 @@ if (require.main === module) {
489489
});
490490
}
491491

492+
/**
493+
* Lazily compiled dynamic import loader function.
494+
*/
495+
let load: (<T>(modulePath: string | URL) => Promise<T>) | undefined;
496+
492497
/**
493498
* This uses a dynamic import to load a module which may be ESM.
494499
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
@@ -502,5 +507,10 @@ if (require.main === module) {
502507
* @returns A Promise that resolves to the dynamically imported module.
503508
*/
504509
export function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
505-
return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise<T>;
510+
load ??= new Function('modulePath', `return import(modulePath);`) as Exclude<
511+
typeof load,
512+
undefined
513+
>;
514+
515+
return load(modulePath);
506516
}

0 commit comments

Comments
 (0)