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.
This commit is contained in:
Charles Lyding 2023-11-02 14:37:45 -04:00 committed by Alan Agius
parent de1ec9da3b
commit 6d8d948ad0
4 changed files with 45 additions and 5 deletions

View File

@ -6,6 +6,11 @@
* found in the LICENSE file at https://angular.io/license
*/
/**
* Lazily compiled dynamic import loader function.
*/
let load: (<T>(modulePath: string | URL) => Promise<T>) | undefined;
/**
* This uses a dynamic import to load a module which may be ESM.
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
@ -19,5 +24,10 @@
* @returns A Promise that resolves to the dynamically imported module.
*/
export function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise<T>;
load ??= new Function('modulePath', `return import(modulePath);`) as Exclude<
typeof load,
undefined
>;
return load(modulePath);
}

View File

@ -213,6 +213,11 @@ export class WorkspaceNodeModulesArchitectHost implements ArchitectHost<NodeModu
}
}
/**
* Lazily compiled dynamic import loader function.
*/
let load: (<T>(modulePath: string | URL) => Promise<T>) | undefined;
/**
* This uses a dynamic import to load a module which may be ESM.
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
@ -225,8 +230,13 @@ export class WorkspaceNodeModulesArchitectHost implements ArchitectHost<NodeModu
* @param modulePath The path of the module to load.
* @returns A Promise that resolves to the dynamically imported module.
*/
function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise<T>;
export function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
load ??= new Function('modulePath', `return import(modulePath);`) as Exclude<
typeof load,
undefined
>;
return load(modulePath);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any

View File

@ -6,6 +6,11 @@
* found in the LICENSE file at https://angular.io/license
*/
/**
* Lazily compiled dynamic import loader function.
*/
let load: (<T>(modulePath: string | URL) => Promise<T>) | undefined;
/**
* This uses a dynamic import to load a module which may be ESM.
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
@ -19,5 +24,10 @@
* @returns A Promise that resolves to the dynamically imported module.
*/
export function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise<T>;
load ??= new Function('modulePath', `return import(modulePath);`) as Exclude<
typeof load,
undefined
>;
return load(modulePath);
}

View File

@ -489,6 +489,11 @@ if (require.main === module) {
});
}
/**
* Lazily compiled dynamic import loader function.
*/
let load: (<T>(modulePath: string | URL) => Promise<T>) | undefined;
/**
* This uses a dynamic import to load a module which may be ESM.
* CommonJS code can load ESM code via a dynamic import. Unfortunately, TypeScript
@ -502,5 +507,10 @@ if (require.main === module) {
* @returns A Promise that resolves to the dynamically imported module.
*/
export function loadEsmModule<T>(modulePath: string | URL): Promise<T> {
return new Function('modulePath', `return import(modulePath);`)(modulePath) as Promise<T>;
load ??= new Function('modulePath', `return import(modulePath);`) as Exclude<
typeof load,
undefined
>;
return load(modulePath);
}