This reverts commit cb142b6df9
.
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 {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 path from 'path';
|
||||
import * as tsickle from 'tsickle';
|
||||
|
@ -35,6 +35,9 @@ export function main(args) {
|
|||
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 {
|
||||
if (args[0] === '-p') args.shift();
|
||||
// Strip leading at-signs, used to indicate a params file
|
||||
|
@ -141,10 +144,8 @@ export function relativeToRootDirs(filePath: string, rootDirs: string[]): string
|
|||
return filePath;
|
||||
}
|
||||
|
||||
export function compile({
|
||||
allDepsCompiledWithBazel = true, compilerOpts, tsHost, bazelOpts, files, inputs, expectedOuts,
|
||||
gatherDiagnostics, bazelHost,
|
||||
}: {
|
||||
export function compile({allDepsCompiledWithBazel = true, compilerOpts, tsHost, bazelOpts, files,
|
||||
inputs, expectedOuts, gatherDiagnostics, bazelHost}: {
|
||||
allDepsCompiledWithBazel?: boolean,
|
||||
compilerOpts: ng.CompilerOptions,
|
||||
tsHost: ts.CompilerHost, inputs?: {[path: string]: string},
|
||||
|
@ -152,15 +153,41 @@ export function compile({
|
|||
files: string[],
|
||||
expectedOuts: string[],
|
||||
gatherDiagnostics?: (program: ng.Program) => ng.Diagnostics,
|
||||
bazelHost?: BazelHost,
|
||||
bazelHost?: CompilerHost,
|
||||
}): {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) {
|
||||
compilerOpts.annotateForClosureCompiler = true;
|
||||
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.
|
||||
if (compilerOpts.enableIvy) {
|
||||
if (isInIvyMode) {
|
||||
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) {
|
||||
const fileLoader = createFileLoader(inputs, bazelOpts);
|
||||
bazelHost = new BazelHost(
|
||||
bazelHost = new CompilerHost(
|
||||
files, compilerOpts, bazelOpts, tsHost, fileLoader, generatedFileModuleResolver);
|
||||
}
|
||||
|
||||
// Also need to disable decorator downleveling in the BazelHost in Ivy mode.
|
||||
if (compilerOpts.enableIvy) {
|
||||
if (isInIvyMode) {
|
||||
bazelHost.transformDecorators = false;
|
||||
}
|
||||
|
||||
|
@ -379,68 +433,6 @@ export function compile({
|
|||
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
|
||||
* is only generated by the compiler if --flatModuleOutFile is specified. But
|
||||
|
|
Loading…
Reference in New Issue