diff --git a/packages/angular/build/src/tools/angular/angular-host.ts b/packages/angular/build/src/tools/angular/angular-host.ts index 1750002f1cdd..103b3e37ac68 100644 --- a/packages/angular/build/src/tools/angular/angular-host.ts +++ b/packages/angular/build/src/tools/angular/angular-host.ts @@ -164,6 +164,7 @@ export function createAngularCompilerHost( typescript: typeof ts, compilerOptions: AngularCompilerOptions, hostOptions: AngularHostOptions, + packageJsonCache: ts.PackageJsonInfoCache | undefined, ): AngularCompilerHost { // Create TypeScript compiler host const host: AngularCompilerHost = typescript.createIncrementalCompilerHost(compilerOptions); @@ -229,16 +230,17 @@ export function createAngularCompilerHost( return hostOptions.modifiedFiles; }; + // Provide a resolution cache to ensure package.json lookups are cached + const resolutionCache = typescript.createModuleResolutionCache( + host.getCurrentDirectory(), + host.getCanonicalFileName.bind(host), + compilerOptions, + packageJsonCache, + ); + host.getModuleResolutionCache = () => resolutionCache; + // Augment TypeScript Host for file replacements option if (hostOptions.fileReplacements) { - // Provide a resolution cache since overriding resolution prevents automatic creation - const resolutionCache = typescript.createModuleResolutionCache( - host.getCurrentDirectory(), - host.getCanonicalFileName.bind(host), - compilerOptions, - ); - host.getModuleResolutionCache = () => resolutionCache; - augmentHostWithReplacements(typescript, host, hostOptions.fileReplacements, resolutionCache); } diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 19e43251e950..f111224c36d8 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -74,25 +74,39 @@ export class AotCompilation extends AngularCompilation { hostOptions.externalStylesheets ??= new Map(); } + // Reuse the package.json cache from the previous compilation + const packageJsonCache = this.#state?.compilerHost + .getModuleResolutionCache?.() + ?.getPackageJsonInfoCache(); + const useHmr = compilerOptions['_enableHmr'] && hostOptions.modifiedFiles && hostOptions.modifiedFiles.size <= HMR_MODIFIED_FILE_LIMIT; - // Collect stale source files for HMR analysis of inline component resources let staleSourceFiles; - if (useHmr && hostOptions.modifiedFiles && this.#state) { + let clearPackageJsonCache = false; + if (hostOptions.modifiedFiles && this.#state) { for (const modifiedFile of hostOptions.modifiedFiles) { - const sourceFile = this.#state.typeScriptProgram.getSourceFile(modifiedFile); - if (sourceFile) { - staleSourceFiles ??= new Map(); - staleSourceFiles.set(modifiedFile, sourceFile); + // Clear package.json cache if a node modules file was modified + if (!clearPackageJsonCache && modifiedFile.includes('node_modules')) { + clearPackageJsonCache = true; + packageJsonCache?.clear(); + } + + // Collect stale source files for HMR analysis of inline component resources + if (useHmr) { + const sourceFile = this.#state.typeScriptProgram.getSourceFile(modifiedFile); + if (sourceFile) { + staleSourceFiles ??= new Map(); + staleSourceFiles.set(modifiedFile, sourceFile); + } } } } // Create Angular compiler host - const host = createAngularCompilerHost(ts, compilerOptions, hostOptions); + const host = createAngularCompilerHost(ts, compilerOptions, hostOptions, packageJsonCache); // Create the Angular specific program that contains the Angular compiler const angularProgram = profileSync( diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index eab21a8608c5..db2de81b4ae7 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -53,7 +53,7 @@ export class JitCompilation extends AngularCompilation { compilerOptionsTransformer?.(originalCompilerOptions) ?? originalCompilerOptions; // Create Angular compiler host - const host = createAngularCompilerHost(ts, compilerOptions, hostOptions); + const host = createAngularCompilerHost(ts, compilerOptions, hostOptions, undefined); // Create the TypeScript Program const typeScriptProgram = profileSync('TS_CREATE_PROGRAM', () =>