This reverts commit cb142b6df9fa3b43e6905358c880c11f6a9abb45. The intention of this commit was for a consumer of the `compile` function to pass the `bazelHost` it returns into future invocations, reusing the `FileCache` between them. However, first-party ngc_wrapped does not do this, which caused a performance regression as the `FileCache` was no longer shared between compilations. PR Close #35063
This commit is contained in:
		
							parent
							
								
									cd9ae66b35
								
							
						
					
					
						commit
						9f5b490800
					
				| @ -7,7 +7,7 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| import * as ng from '@angular/compiler-cli'; | import * as ng from '@angular/compiler-cli'; | ||||||
| import {BazelOptions, CachedFileLoader, CompilerHost as BazelHost, FileCache, FileLoader, UncachedFileLoader, constructManifest, debug, parseTsconfig, resolveNormalizedPath, runAsWorker, runWorkerLoop} from '@bazel/typescript'; | import {BazelOptions, CachedFileLoader, CompilerHost, FileCache, FileLoader, UncachedFileLoader, constructManifest, debug, parseTsconfig, resolveNormalizedPath, runAsWorker, runWorkerLoop} from '@bazel/typescript'; | ||||||
| import * as fs from 'fs'; | import * as fs from 'fs'; | ||||||
| import * as path from 'path'; | import * as path from 'path'; | ||||||
| import * as tsickle from 'tsickle'; | import * as tsickle from 'tsickle'; | ||||||
| @ -35,6 +35,9 @@ export function main(args) { | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /** The one FileCache instance used in this process. */ | ||||||
|  | const fileCache = new FileCache<ts.SourceFile>(debug); | ||||||
|  | 
 | ||||||
| export function runOneBuild(args: string[], inputs?: {[path: string]: string}): boolean { | export function runOneBuild(args: string[], inputs?: {[path: string]: string}): boolean { | ||||||
|   if (args[0] === '-p') args.shift(); |   if (args[0] === '-p') args.shift(); | ||||||
|   // Strip leading at-signs, used to indicate a params file
 |   // Strip leading at-signs, used to indicate a params file
 | ||||||
| @ -141,10 +144,8 @@ export function relativeToRootDirs(filePath: string, rootDirs: string[]): string | |||||||
|   return filePath; |   return filePath; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function compile({ | export function compile({allDepsCompiledWithBazel = true, compilerOpts, tsHost, bazelOpts, files, | ||||||
|     allDepsCompiledWithBazel = true, compilerOpts, tsHost, bazelOpts, files, inputs, expectedOuts, |                          inputs, expectedOuts, gatherDiagnostics, bazelHost}: { | ||||||
|     gatherDiagnostics, bazelHost, |  | ||||||
| }: { |  | ||||||
|   allDepsCompiledWithBazel?: boolean, |   allDepsCompiledWithBazel?: boolean, | ||||||
|   compilerOpts: ng.CompilerOptions, |   compilerOpts: ng.CompilerOptions, | ||||||
|   tsHost: ts.CompilerHost, inputs?: {[path: string]: string}, |   tsHost: ts.CompilerHost, inputs?: {[path: string]: string}, | ||||||
| @ -152,15 +153,41 @@ export function compile({ | |||||||
|   files: string[], |   files: string[], | ||||||
|   expectedOuts: string[], |   expectedOuts: string[], | ||||||
|   gatherDiagnostics?: (program: ng.Program) => ng.Diagnostics, |   gatherDiagnostics?: (program: ng.Program) => ng.Diagnostics, | ||||||
|   bazelHost?: BazelHost, |   bazelHost?: CompilerHost, | ||||||
| }): {diagnostics: ng.Diagnostics, program: ng.Program} { | }): {diagnostics: ng.Diagnostics, program: ng.Program} { | ||||||
|  |   let fileLoader: FileLoader; | ||||||
|  | 
 | ||||||
|  |   if (bazelOpts.maxCacheSizeMb !== undefined) { | ||||||
|  |     const maxCacheSizeBytes = bazelOpts.maxCacheSizeMb * (1 << 20); | ||||||
|  |     fileCache.setMaxCacheSize(maxCacheSizeBytes); | ||||||
|  |   } else { | ||||||
|  |     fileCache.resetMaxCacheSize(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (inputs) { | ||||||
|  |     fileLoader = new CachedFileLoader(fileCache); | ||||||
|  |     // Resolve the inputs to absolute paths to match TypeScript internals
 | ||||||
|  |     const resolvedInputs = new Map<string, string>(); | ||||||
|  |     const inputKeys = Object.keys(inputs); | ||||||
|  |     for (let i = 0; i < inputKeys.length; i++) { | ||||||
|  |       const key = inputKeys[i]; | ||||||
|  |       resolvedInputs.set(resolveNormalizedPath(key), inputs[key]); | ||||||
|  |     } | ||||||
|  |     fileCache.updateCache(resolvedInputs); | ||||||
|  |   } else { | ||||||
|  |     fileLoader = new UncachedFileLoader(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (!bazelOpts.es5Mode) { |   if (!bazelOpts.es5Mode) { | ||||||
|     compilerOpts.annotateForClosureCompiler = true; |     compilerOpts.annotateForClosureCompiler = true; | ||||||
|     compilerOpts.annotationsAs = 'static fields'; |     compilerOpts.annotationsAs = 'static fields'; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   // Detect from compilerOpts whether the entrypoint is being invoked in Ivy mode.
 | ||||||
|  |   const isInIvyMode = compilerOpts.enableIvy === 'ngtsc'; | ||||||
|  | 
 | ||||||
|   // Disable downleveling and Closure annotation if in Ivy mode.
 |   // Disable downleveling and Closure annotation if in Ivy mode.
 | ||||||
|   if (compilerOpts.enableIvy) { |   if (isInIvyMode) { | ||||||
|     compilerOpts.annotationsAs = 'decorators'; |     compilerOpts.annotationsAs = 'decorators'; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -185,14 +212,41 @@ export function compile({ | |||||||
|         } |         } | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|  |   // Patch fileExists when resolving modules, so that CompilerHost can ask TypeScript to
 | ||||||
|  |   // resolve non-existing generated files that don't exist on disk, but are
 | ||||||
|  |   // synthetic and added to the `programWithStubs` based on real inputs.
 | ||||||
|  |   const generatedFileModuleResolverHost = Object.create(tsHost); | ||||||
|  |   generatedFileModuleResolverHost.fileExists = (fileName: string) => { | ||||||
|  |     const match = NGC_GEN_FILES.exec(fileName); | ||||||
|  |     if (match) { | ||||||
|  |       const [, file, suffix, ext] = match; | ||||||
|  |       // Performance: skip looking for files other than .d.ts or .ts
 | ||||||
|  |       if (ext !== '.ts' && ext !== '.d.ts') return false; | ||||||
|  |       if (suffix.indexOf('ngstyle') >= 0) { | ||||||
|  |         // Look for foo.css on disk
 | ||||||
|  |         fileName = file; | ||||||
|  |       } else { | ||||||
|  |         // Look for foo.d.ts or foo.ts on disk
 | ||||||
|  |         fileName = file + (ext || ''); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return tsHost.fileExists(fileName); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   function generatedFileModuleResolver( | ||||||
|  |       moduleName: string, containingFile: string, | ||||||
|  |       compilerOptions: ts.CompilerOptions): ts.ResolvedModuleWithFailedLookupLocations { | ||||||
|  |     return ts.resolveModuleName( | ||||||
|  |         moduleName, containingFile, compilerOptions, generatedFileModuleResolverHost); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (!bazelHost) { |   if (!bazelHost) { | ||||||
|     const fileLoader = createFileLoader(inputs, bazelOpts); |     bazelHost = new CompilerHost( | ||||||
|     bazelHost = new BazelHost( |  | ||||||
|         files, compilerOpts, bazelOpts, tsHost, fileLoader, generatedFileModuleResolver); |         files, compilerOpts, bazelOpts, tsHost, fileLoader, generatedFileModuleResolver); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // Also need to disable decorator downleveling in the BazelHost in Ivy mode.
 |   // Also need to disable decorator downleveling in the BazelHost in Ivy mode.
 | ||||||
|   if (compilerOpts.enableIvy) { |   if (isInIvyMode) { | ||||||
|     bazelHost.transformDecorators = false; |     bazelHost.transformDecorators = false; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -379,68 +433,6 @@ export function compile({ | |||||||
|   return {program, diagnostics}; |   return {program, diagnostics}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** A module resolver for handling generated files in Bazel. */ |  | ||||||
| export function generatedFileModuleResolver( |  | ||||||
|     moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions, |  | ||||||
|     host: ts.ModuleResolutionHost, ): ts.ResolvedModuleWithFailedLookupLocations { |  | ||||||
|   // Patch fileExists when resolving modules, so that CompilerHost can ask
 |  | ||||||
|   // TypeScript to resolve non-existing generated files that don't exist on
 |  | ||||||
|   // disk, but are synthetic and added to the `programWithStubs` based on real
 |  | ||||||
|   // inputs.
 |  | ||||||
|   const generatedFileModuleResolverHost = Object.assign({}, host, { |  | ||||||
|     fileExists: (...[fileName, ...rest]: Parameters<typeof host.fileExists>): |  | ||||||
|                     ReturnType<typeof host.fileExists> => { |  | ||||||
|                       const match = NGC_GEN_FILES.exec(fileName); |  | ||||||
|                       if (match) { |  | ||||||
|                         const [, file, suffix, ext] = match; |  | ||||||
|                         // Performance: skip looking for files other than .d.ts or .ts
 |  | ||||||
|                         if (ext !== '.ts' && ext !== '.d.ts') return false; |  | ||||||
|                         if (suffix.indexOf('ngstyle') >= 0) { |  | ||||||
|                           // Look for foo.css on disk
 |  | ||||||
|                           fileName = file; |  | ||||||
|                         } else { |  | ||||||
|                           // Look for foo.d.ts or foo.ts on disk
 |  | ||||||
|                           fileName = file + (ext || ''); |  | ||||||
|                         } |  | ||||||
|                       } |  | ||||||
| 
 |  | ||||||
|                       return host.fileExists(fileName, ...rest); |  | ||||||
|                     }, |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   return ts.resolveModuleName( |  | ||||||
|       moduleName, containingFile, compilerOptions, generatedFileModuleResolverHost); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** Creates a {@link FileLoader} to cache Bazel inputs.*/ |  | ||||||
| export function createFileLoader( |  | ||||||
|     inputs: {[key: string]: string} | undefined, bazelOpts: BazelOptions): FileLoader { |  | ||||||
|   /** The one FileCache instance used in this process. */ |  | ||||||
|   const fileCache = new FileCache<ts.SourceFile>(debug); |  | ||||||
| 
 |  | ||||||
|   if (bazelOpts.maxCacheSizeMb !== undefined) { |  | ||||||
|     const maxCacheSizeBytes = bazelOpts.maxCacheSizeMb * (1 << 20); |  | ||||||
|     fileCache.setMaxCacheSize(maxCacheSizeBytes); |  | ||||||
|   } else { |  | ||||||
|     fileCache.resetMaxCacheSize(); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   if (inputs) { |  | ||||||
|     const fileLoader = new CachedFileLoader(fileCache); |  | ||||||
|     // Resolve the inputs to absolute paths to match TypeScript internals
 |  | ||||||
|     const resolvedInputs = new Map<string, string>(); |  | ||||||
|     const inputKeys = Object.keys(inputs); |  | ||||||
|     for (let i = 0; i < inputKeys.length; i++) { |  | ||||||
|       const key = inputKeys[i]; |  | ||||||
|       resolvedInputs.set(resolveNormalizedPath(key), inputs[key]); |  | ||||||
|     } |  | ||||||
|     fileCache.updateCache(resolvedInputs); |  | ||||||
|     return fileLoader; |  | ||||||
|   } else { |  | ||||||
|     return new UncachedFileLoader(); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** | /** | ||||||
|  * Generate metadata.json for the specified `files`. By default, metadata.json |  * Generate metadata.json for the specified `files`. By default, metadata.json | ||||||
|  * is only generated by the compiler if --flatModuleOutFile is specified. But |  * is only generated by the compiler if --flatModuleOutFile is specified. But | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user