perf(ngcc): use the EntryPointManifest
in DirectoryWalkerEntryPointFinder
(#35931)
The `DirectoryWalkerEntryPointFinder` has to traverse the entire node_modules library everytime it executes in order to identify the entry-points that need to be processed. This is very time consuming (several seconds for big projects on Windows). This commit changes the `DirectoryWalkerEntryPointFinder` to use the `EntryPointManifest` to store the paths to entry-points that were found when doing this initial node_modules traversal in a file to be reused for subsequent calls. This dramatically speeds up ngcc processing when it has been run once already. PR Close #35931
This commit is contained in:

committed by
Andrew Kushnir

parent
560542c2a8
commit
ec9f4d5bc6
@ -10,6 +10,7 @@ import {DependencyResolver, SortedEntryPointsInfo} from '../dependencies/depende
|
||||
import {Logger} from '../logging/logger';
|
||||
import {NgccConfiguration} from '../packages/configuration';
|
||||
import {EntryPoint, INVALID_ENTRY_POINT, NO_ENTRY_POINT, getEntryPointInfo} from '../packages/entry_point';
|
||||
import {EntryPointManifest} from '../packages/entry_point_manifest';
|
||||
import {PathMappings} from '../utils';
|
||||
import {NGCC_DIRECTORY} from '../writing/new_entry_point_file_writer';
|
||||
import {EntryPointFinder} from './interface';
|
||||
@ -23,16 +24,28 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
|
||||
private basePaths = getBasePaths(this.sourceDirectory, this.pathMappings);
|
||||
constructor(
|
||||
private fs: FileSystem, private config: NgccConfiguration, private logger: Logger,
|
||||
private resolver: DependencyResolver, private sourceDirectory: AbsoluteFsPath,
|
||||
private pathMappings: PathMappings|undefined) {}
|
||||
private resolver: DependencyResolver, private entryPointManifest: EntryPointManifest,
|
||||
private sourceDirectory: AbsoluteFsPath, private pathMappings: PathMappings|undefined) {}
|
||||
/**
|
||||
* Search the `sourceDirectory`, and sub-directories, using `pathMappings` as necessary, to find
|
||||
* all package entry-points.
|
||||
*/
|
||||
findEntryPoints(): SortedEntryPointsInfo {
|
||||
const unsortedEntryPoints = this.basePaths.reduce<EntryPoint[]>(
|
||||
(entryPoints, basePath) => entryPoints.concat(this.walkDirectoryForEntryPoints(basePath)),
|
||||
[]);
|
||||
const unsortedEntryPoints: EntryPoint[] = [];
|
||||
for (const basePath of this.basePaths) {
|
||||
let entryPoints = this.entryPointManifest.readEntryPointsUsingManifest(basePath);
|
||||
if (entryPoints === null) {
|
||||
this.logger.debug(
|
||||
`No manifest found for ${basePath} so walking the directories for entry-points.`);
|
||||
const startTime = Date.now();
|
||||
entryPoints = this.walkDirectoryForEntryPoints(basePath);
|
||||
const duration = Math.round((Date.now() - startTime) / 100) / 10;
|
||||
this.logger.debug(`Walking directories took ${duration}s.`);
|
||||
|
||||
this.entryPointManifest.writeEntryPointManifest(basePath, entryPoints);
|
||||
}
|
||||
unsortedEntryPoints.push(...entryPoints);
|
||||
}
|
||||
return this.resolver.sortEntryPointsByDependency(unsortedEntryPoints);
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ import {hasBeenProcessed} from './packages/build_marker';
|
||||
import {NgccConfiguration} from './packages/configuration';
|
||||
import {EntryPoint, EntryPointJsonProperty, EntryPointPackageJson, SUPPORTED_FORMAT_PROPERTIES, getEntryPointFormat} from './packages/entry_point';
|
||||
import {makeEntryPointBundle} from './packages/entry_point_bundle';
|
||||
import {EntryPointManifest} from './packages/entry_point_manifest';
|
||||
import {Transformer} from './packages/transformer';
|
||||
import {PathMappings} from './utils';
|
||||
import {cleanOutdatedPackages} from './writing/cleaning/package_cleaner';
|
||||
@ -153,14 +154,15 @@ export function mainNgcc(
|
||||
const absBasePath = absoluteFrom(basePath);
|
||||
const config = new NgccConfiguration(fileSystem, dirname(absBasePath));
|
||||
const dependencyResolver = getDependencyResolver(fileSystem, logger, config, pathMappings);
|
||||
const entryPointManifest = new EntryPointManifest(fileSystem, config, logger);
|
||||
|
||||
// Bail out early if the work is already done.
|
||||
const supportedPropertiesToConsider = ensureSupportedProperties(propertiesToConsider);
|
||||
const absoluteTargetEntryPointPath =
|
||||
targetEntryPointPath !== undefined ? resolve(basePath, targetEntryPointPath) : null;
|
||||
const finder = getEntryPointFinder(
|
||||
fileSystem, logger, dependencyResolver, config, absBasePath, absoluteTargetEntryPointPath,
|
||||
pathMappings);
|
||||
fileSystem, logger, dependencyResolver, config, entryPointManifest, absBasePath,
|
||||
absoluteTargetEntryPointPath, pathMappings);
|
||||
if (finder instanceof TargetedEntryPointFinder &&
|
||||
!finder.targetNeedsProcessingOrCleaning(supportedPropertiesToConsider, compileAllFormats)) {
|
||||
logger.debug('The target entry-point has already been processed');
|
||||
@ -376,14 +378,15 @@ function getDependencyResolver(
|
||||
|
||||
function getEntryPointFinder(
|
||||
fs: FileSystem, logger: Logger, resolver: DependencyResolver, config: NgccConfiguration,
|
||||
basePath: AbsoluteFsPath, absoluteTargetEntryPointPath: AbsoluteFsPath | null,
|
||||
entryPointManifest: EntryPointManifest, basePath: AbsoluteFsPath,
|
||||
absoluteTargetEntryPointPath: AbsoluteFsPath | null,
|
||||
pathMappings: PathMappings | undefined): EntryPointFinder {
|
||||
if (absoluteTargetEntryPointPath !== null) {
|
||||
return new TargetedEntryPointFinder(
|
||||
fs, config, logger, resolver, basePath, absoluteTargetEntryPointPath, pathMappings);
|
||||
} else {
|
||||
return new DirectoryWalkerEntryPointFinder(
|
||||
fs, config, logger, resolver, basePath, pathMappings);
|
||||
fs, config, logger, resolver, entryPointManifest, basePath, pathMappings);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user