perf(ivy): use module resolution cache (#34332)
During TypeScript module resolution, a lot of filesystem requests are done. This is quite an expensive operation, so a module resolution cache can be used to speed up the process significantly. This commit lets the Ivy compiler perform all module resolution with a module resolution cache. Note that the module resolution behavior can be changed with a custom compiler host, in which case that custom host implementation is responsible for caching. In the case of the Angular CLI a custom compiler host with proper module resolution caching is already in place, so the CLI already has this optimization. PR Close #34332
This commit is contained in:
@ -8,13 +8,14 @@
|
||||
import {Expression, ExternalExpr, ExternalReference, WrappedNodeExpr} from '@angular/compiler';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {LogicalFileSystem, LogicalProjectPath, PathSegment, absoluteFrom, absoluteFromSourceFile, basename, dirname, relative, resolve} from '../../file_system';
|
||||
import {LogicalFileSystem, LogicalProjectPath, PathSegment, absoluteFromSourceFile, dirname, relative} from '../../file_system';
|
||||
import {stripExtension} from '../../file_system/src/util';
|
||||
import {ReflectionHost} from '../../reflection';
|
||||
import {getSourceFile, getSourceFileOrNull, isDeclaration, nodeNameForError, resolveModuleName} from '../../util/src/typescript';
|
||||
import {getSourceFile, isDeclaration, nodeNameForError} from '../../util/src/typescript';
|
||||
|
||||
import {findExportedNameOfNode} from './find_export';
|
||||
import {ImportMode, Reference} from './references';
|
||||
import {ModuleResolver} from './resolver';
|
||||
|
||||
|
||||
|
||||
@ -118,8 +119,7 @@ export class AbsoluteModuleStrategy implements ReferenceEmitStrategy {
|
||||
|
||||
constructor(
|
||||
protected program: ts.Program, protected checker: ts.TypeChecker,
|
||||
protected options: ts.CompilerOptions, protected host: ts.CompilerHost,
|
||||
private reflectionHost: ReflectionHost) {}
|
||||
protected moduleResolver: ModuleResolver, private reflectionHost: ReflectionHost) {}
|
||||
|
||||
emit(ref: Reference<ts.Node>, context: ts.SourceFile, importMode: ImportMode): Expression|null {
|
||||
if (ref.bestGuessOwningModule === null) {
|
||||
@ -165,13 +165,7 @@ export class AbsoluteModuleStrategy implements ReferenceEmitStrategy {
|
||||
protected enumerateExportsOfModule(specifier: string, fromFile: string):
|
||||
Map<ts.Declaration, string>|null {
|
||||
// First, resolve the module specifier to its entry point, and get the ts.Symbol for it.
|
||||
const resolvedModule = resolveModuleName(specifier, fromFile, this.options, this.host);
|
||||
if (resolvedModule === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const entryPointFile =
|
||||
getSourceFileOrNull(this.program, absoluteFrom(resolvedModule.resolvedFileName));
|
||||
const entryPointFile = this.moduleResolver.resolveModule(specifier, fromFile);
|
||||
if (entryPointFile === null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -8,12 +8,6 @@
|
||||
import * as ts from 'typescript';
|
||||
import {absoluteFrom} from '../../file_system';
|
||||
import {getSourceFileOrNull, resolveModuleName} from '../../util/src/typescript';
|
||||
import {Reference} from './references';
|
||||
|
||||
export interface ReferenceResolver {
|
||||
resolve(decl: ts.Declaration, importFromHint: string|null, fromFile: string):
|
||||
Reference<ts.Declaration>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by `RouterEntryPointManager` and `NgModuleRouteAnalyzer` (which is in turn is used by
|
||||
@ -24,11 +18,12 @@ export interface ReferenceResolver {
|
||||
export class ModuleResolver {
|
||||
constructor(
|
||||
private program: ts.Program, private compilerOptions: ts.CompilerOptions,
|
||||
private host: ts.CompilerHost) {}
|
||||
private host: ts.CompilerHost, private moduleResolutionCache: ts.ModuleResolutionCache|null) {
|
||||
}
|
||||
|
||||
resolveModuleName(module: string, containingFile: ts.SourceFile): ts.SourceFile|null {
|
||||
const resolved =
|
||||
resolveModuleName(module, containingFile.fileName, this.compilerOptions, this.host);
|
||||
resolveModule(moduleName: string, containingFile: string): ts.SourceFile|null {
|
||||
const resolved = resolveModuleName(
|
||||
moduleName, containingFile, this.compilerOptions, this.host, this.moduleResolutionCache);
|
||||
if (resolved === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user