From dfefd6ba4fcda6baa3dc172978ca84acaa48ec54 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 11 Mar 2021 11:22:33 -0500 Subject: [PATCH] perf(@ngtools/webpack): use precalculated dependencies in unused file check This change uses the newly introduced precalculated file dependencies for each TypeScript file instead of querying TypeScript for the SourceFile's dependencies when performing the unused file check at the end of the build cycle. This change removes the need to recalculate the dependencies for each TypeScript file present in the Webpack compilation. --- packages/ngtools/webpack/src/ivy/plugin.ts | 31 ++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/ngtools/webpack/src/ivy/plugin.ts b/packages/ngtools/webpack/src/ivy/plugin.ts index 1216a0ef3e87..85da94e30ee8 100644 --- a/packages/ngtools/webpack/src/ivy/plugin.ts +++ b/packages/ngtools/webpack/src/ivy/plugin.ts @@ -137,7 +137,7 @@ export class AngularWebpackPlugin { // Example: module -> module__ivy_ngcc resolverFactoryHooks.resolveOptions .for('normal') - .tap(PLUGIN_NAME, (resolveOptions: { mainFields: string[], plugins: unknown[] }) => { + .tap(PLUGIN_NAME, (resolveOptions: { mainFields: string[]; plugins: unknown[] }) => { const originalMainFields = resolveOptions.mainFields; const ivyMainFields = originalMainFields.map((f) => `${f}_ivy_ngcc`); @@ -273,15 +273,12 @@ export class AngularWebpackPlugin { const currentUnused = new Set( allProgramFiles .filter((sourceFile) => !sourceFile.isDeclarationFile) - .map((sourceFile) => sourceFile.fileName), + .map((sourceFile) => normalizePath(sourceFile.fileName)), ); Array.from(modules).forEach(({ resource }: compilation.Module & { resource?: string }) => { - const sourceFile = resource && builder.getSourceFile(resource); - if (!sourceFile) { - return; + if (resource) { + this.markResourceUsed(normalizePath(resource), currentUnused); } - - builder.getAllDependencies(sourceFile).forEach((dep) => currentUnused.delete(dep)); }); for (const unused of currentUnused) { if (previousUnused && previousUnused.has(unused)) { @@ -301,6 +298,24 @@ export class AngularWebpackPlugin { }); } + private markResourceUsed( + normalizedResourcePath: string, + currentUnused: Set, + ): void { + if (!currentUnused.has(normalizedResourcePath)) { + return; + } + + currentUnused.delete(normalizedResourcePath); + const dependencies = this.fileDependencies.get(normalizedResourcePath); + if (!dependencies) { + return; + } + for (const dependency of dependencies) { + this.markResourceUsed(normalizePath(dependency), currentUnused); + } + } + private async rebuildRequiredFiles( modules: Iterable, compilation: WebpackCompilation, @@ -599,7 +614,7 @@ export class AngularWebpackPlugin { } const dependencies = [ - ...this.fileDependencies.get(filePath) || [], + ...(this.fileDependencies.get(filePath) || []), ...getExtraDependencies(sourceFile), ].map(externalizePath);