Skip to content

Commit f394ba0

Browse files
alexeaglematsko
authored andcommitted
fix(bazel): Cache fileNameToModuleName lookups (#25731)
This saves expensive re-parsing of the file when not run as a Bazel worker PR Close #25731
1 parent 268cf79 commit f394ba0

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

packages/bazel/src/ngc-wrapped/index.ts

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -224,23 +224,29 @@ export function compile({allowNonHermeticReads, allDepsCompiledWithBazel = true,
224224
};
225225

226226
const ngHost = ng.createCompilerHost({options: compilerOpts, tsHost: bazelHost});
227-
227+
const fileNameToModuleNameCache = new Map<string, string>();
228228
ngHost.fileNameToModuleName = (importedFilePath: string, containingFilePath: string) => {
229-
// Lookup the module name specified in the TypeScript source file, if present
230-
// it will look like ///<amd module-name="something"/>
231-
// For performance, we only do this for .d.ts files, to avoid parsing lots of
232-
// additional files that were not in the program.
233-
// (We don't have the ts.Program available in this codepath)
234-
if (importedFilePath.endsWith('.d.ts')) {
235-
try {
236-
const sourceFile = ngHost.getSourceFile(importedFilePath, ts.ScriptTarget.Latest);
237-
if (sourceFile && sourceFile.moduleName) {
238-
return sourceFile.moduleName;
239-
}
240-
} catch (err) {
241-
// File does not exist or parse error. Ignore this case and continue onto the
242-
// other methods of resolving the module below.
229+
// Memoize this lookup to avoid expensive re-parses of the same file
230+
// When run as a worker, the actual ts.SourceFile is cached
231+
// but when we don't run as a worker, there is no cache.
232+
// For one example target in g3, we saw a cache hit rate of 7590/7695
233+
if (fileNameToModuleNameCache.has(importedFilePath)) {
234+
return fileNameToModuleNameCache.get(importedFilePath);
235+
}
236+
const result = doFileNameToModuleName(importedFilePath);
237+
fileNameToModuleNameCache.set(importedFilePath, result);
238+
return result;
239+
};
240+
241+
function doFileNameToModuleName(importedFilePath: string): string {
242+
try {
243+
const sourceFile = ngHost.getSourceFile(importedFilePath, ts.ScriptTarget.Latest);
244+
if (sourceFile && sourceFile.moduleName) {
245+
return sourceFile.moduleName;
243246
}
247+
} catch (err) {
248+
// File does not exist or parse error. Ignore this case and continue onto the
249+
// other methods of resolving the module below.
244250
}
245251
if ((compilerOpts.module === ts.ModuleKind.UMD || compilerOpts.module === ts.ModuleKind.AMD) &&
246252
ngHost.amdModuleName) {
@@ -251,7 +257,8 @@ export function compile({allowNonHermeticReads, allDepsCompiledWithBazel = true,
251257
return result.substr(NODE_MODULES.length);
252258
}
253259
return bazelOpts.workspaceName + '/' + result;
254-
};
260+
}
261+
255262
ngHost.toSummaryFileName = (fileName: string, referringSrcFileName: string) => path.posix.join(
256263
bazelOpts.workspaceName,
257264
relativeToRootDirs(fileName, compilerOpts.rootDirs).replace(EXT, ''));

0 commit comments

Comments
 (0)