When profiling ngcc it is notable that a large amount of time is spent dealing with an exception that is thrown (and handled internally by fs) when checking the existence of a file. We check file existence a lot in both finding entry-points and when TS is compiling code. This commit adds a simple cached `FileSystem`, which wraps a real `FileSystem` delegate. This will reduce the number of calls through to `fs.exists()` and `fs.readFile()` on the delegate. Initial benchmarks indicate that the cache is miss to hit ratio for `exists()` is about 2:1, which means that we save about 1/3 of the calls to `fs.existsSync()`. Note that this implements a "non-expiring" cache, so it is not suitable for a long lived `FileSystem`, where files may be modified externally. The cache will be updated if a file is changed or moved via calls to `FileSystem` methods but it will not be aware of changes to the files system from outside the `FileSystem` service. For ngcc we must create a new `FileSystem` service for each run of `mainNgcc` and ensure that all file operations (including TS compilation) use the `FileSystem` service. This ensures that it is very unlikely that a file will change externally during `mainNgcc` processing. PR Close #30525
		
			
				
	
	
		
			30 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			30 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
/**
 | 
						|
 * @license
 | 
						|
 * Copyright Google Inc. All Rights Reserved.
 | 
						|
 *
 | 
						|
 * Use of this source code is governed by an MIT-style license that can be
 | 
						|
 * found in the LICENSE file at https://angular.io/license
 | 
						|
 */
 | 
						|
import {CachedFileSystem, NodeJSFileSystem, setFileSystem} from '../src/ngtsc/file_system';
 | 
						|
 | 
						|
import {mainNgcc} from './src/main';
 | 
						|
import {hasBeenProcessed as _hasBeenProcessed} from './src/packages/build_marker';
 | 
						|
import {EntryPointJsonProperty, EntryPointPackageJson} from './src/packages/entry_point';
 | 
						|
 | 
						|
export {ConsoleLogger, LogLevel} from './src/logging/console_logger';
 | 
						|
export {Logger} from './src/logging/logger';
 | 
						|
export {NgccOptions} from './src/main';
 | 
						|
export {PathMappings} from './src/utils';
 | 
						|
 | 
						|
export function hasBeenProcessed(packageJson: object, format: string) {
 | 
						|
  // Recreate the file system on each call to reset the cache
 | 
						|
  setFileSystem(new CachedFileSystem(new NodeJSFileSystem()));
 | 
						|
  return _hasBeenProcessed(packageJson as EntryPointPackageJson, format as EntryPointJsonProperty);
 | 
						|
}
 | 
						|
 | 
						|
export function process(...args: Parameters<typeof mainNgcc>) {
 | 
						|
  // Recreate the file system on each call to reset the cache
 | 
						|
  setFileSystem(new CachedFileSystem(new NodeJSFileSystem()));
 | 
						|
  return mainNgcc(...args);
 | 
						|
}
 |