perf(compiler-cli): ensure module resolution cache is reused for type-check program (#39693)

The Angular compiler creates two `ts.Program`s; one for emit and one for
template type-checking. The creation of the type-check program could
benefit from reusing the `ts.ModuleResolutionCache` that was primed
during the creation of the emit program. This requires that the compiler
host implements `resolveModuleNames`, as otherwise TypeScript will setup
a `ts.ModuleResolutionHost` of its own for both programs.

This commit ensures that `resolveModuleNames` is always implemented,
even if the originally provided compiler host does not. This is
beneficial for the `ngc` binary.

PR Close #39693
This commit is contained in:
JoostK 2020-11-14 20:37:27 +01:00 committed by Andrew Kushnir
parent e29a29ce9f
commit b50d88073e
1 changed files with 19 additions and 0 deletions

View File

@ -101,6 +101,12 @@ export class NgCompilerHost extends DelegatingCompilerHost implements
this.constructionDiagnostics = diagnostics;
this.inputFiles = [...inputFiles, ...shimAdapter.extraInputFiles];
this.rootDirs = rootDirs;
if (this.resolveModuleNames === undefined) {
// In order to reuse the module resolution cache during the creation of the type-check
// program, we'll need to provide `resolveModuleNames` if the delegate did not provide one.
this.resolveModuleNames = this.createCachedResolveModuleNamesFunction();
}
}
/**
@ -263,4 +269,17 @@ export class NgCompilerHost extends DelegatingCompilerHost implements
get unifiedModulesHost(): UnifiedModulesHost|null {
return this.fileNameToModuleName !== undefined ? this as UnifiedModulesHost : null;
}
private createCachedResolveModuleNamesFunction(): ts.CompilerHost['resolveModuleNames'] {
const moduleResolutionCache = ts.createModuleResolutionCache(
this.getCurrentDirectory(), this.getCanonicalFileName.bind(this));
return (moduleNames, containingFile, reusedNames, redirectedReference, options) => {
return moduleNames.map(moduleName => {
const module = ts.resolveModuleName(
moduleName, containingFile, options, this, moduleResolutionCache, redirectedReference);
return module.resolvedModule;
});
};
}
}