From b942d2ea65dbf74212d111376ec826a5db31509a Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 23 Jun 2022 16:20:21 +0200 Subject: [PATCH] use a different _internal_ API to get the output file names for a TS input file and its config... way faster than creating a program and using its internal API but needs some massage... --- build/lib/tsb/index.js | 2 +- build/lib/tsb/index.ts | 2 +- build/lib/tsb/transpiler.js | 35 ++++++++++++----------- build/lib/tsb/transpiler.ts | 57 ++++++++++++++++++------------------- 4 files changed, 47 insertions(+), 49 deletions(-) diff --git a/build/lib/tsb/index.js b/build/lib/tsb/index.js index adab557fe87..a0b6423bb61 100644 --- a/build/lib/tsb/index.js +++ b/build/lib/tsb/index.js @@ -92,7 +92,7 @@ function create(projectPath, existingOptions, config, onError = _defaultOnError) } let result; if (config.transpileOnly) { - const transpiler = new transpiler_1.Transpiler(logFn, printDiagnostic, cmdLine); + const transpiler = new transpiler_1.Transpiler(logFn, printDiagnostic, projectPath, cmdLine); result = (() => createTranspileStream(transpiler)); } else { diff --git a/build/lib/tsb/index.ts b/build/lib/tsb/index.ts index 1164efc9d03..384a6beeb93 100644 --- a/build/lib/tsb/index.ts +++ b/build/lib/tsb/index.ts @@ -126,7 +126,7 @@ export function create( let result: IncrementalCompiler; if (config.transpileOnly) { - const transpiler = new Transpiler(logFn, printDiagnostic, cmdLine); + const transpiler = new Transpiler(logFn, printDiagnostic, projectPath, cmdLine); result = (() => createTranspileStream(transpiler)); } else { const _builder = builder.createTypeScriptBuilder({ logFn }, projectPath, cmdLine); diff --git a/build/lib/tsb/transpiler.js b/build/lib/tsb/transpiler.js index 406075bbf8e..7da255d529f 100644 --- a/build/lib/tsb/transpiler.js +++ b/build/lib/tsb/transpiler.js @@ -113,28 +113,29 @@ class TranspileWorker { } TranspileWorker.pool = 1; class Transpiler { - constructor(logFn, _onError, _cmdLine) { + constructor(logFn, _onError, configFilePath, _cmdLine) { this._onError = _onError; this._cmdLine = _cmdLine; this._workerPool = []; this._queue = []; this._allJobs = []; - this._tsApiInternalOutfileName = new class { - constructor(parsedCmd) { - const host = ts.createCompilerHost(parsedCmd.options); - const program = ts.createProgram({ options: parsedCmd.options, rootNames: parsedCmd.fileNames, host }); - const emitHost = { - getCompilerOptions: () => parsedCmd.options, - getCurrentDirectory: () => host.getCurrentDirectory(), - getCanonicalFileName: file => host.getCanonicalFileName(file), - getCommonSourceDirectory: () => program.getCommonSourceDirectory() - }; - this.getForInfile = file => { - return ts.getOwnEmitOutputFilePath(file, emitHost, '.js'); - }; - } - }(this._cmdLine); logFn('Transpile', `will use ${Transpiler.P} transpile worker`); + this._getOutputFileName = (file) => { + if (!_cmdLine.options.configFilePath) { + // this is needed for the INTERNAL getOutputFileNames-call below... + _cmdLine.options.configFilePath = configFilePath; + } + const isDts = file.endsWith('.d.ts'); + if (isDts) { + file = file.slice(0, -5) + '.ts'; + _cmdLine.fileNames.push(file); + } + const outfile = ts.getOutputFileNames(_cmdLine, file, true)[0]; + if (isDts) { + _cmdLine.fileNames.pop(); + } + return outfile; + }; } async join() { // wait for all penindg jobs @@ -163,7 +164,7 @@ class Transpiler { // kinda LAZYily create workers if (this._workerPool.length === 0) { for (let i = 0; i < Transpiler.P; i++) { - this._workerPool.push(new TranspileWorker(file => this._tsApiInternalOutfileName.getForInfile(file))); + this._workerPool.push(new TranspileWorker(file => this._getOutputFileName(file))); } } const freeWorker = this._workerPool.filter(w => !w.isBusy); diff --git a/build/lib/tsb/transpiler.ts b/build/lib/tsb/transpiler.ts index ad515263f6c..3afc3547dd5 100644 --- a/build/lib/tsb/transpiler.ts +++ b/build/lib/tsb/transpiler.ts @@ -146,6 +146,8 @@ export class Transpiler { static P = Math.floor(cpus().length * .5); + private readonly _getOutputFileName: (name: string) => string; + public onOutfile?: (file: Vinyl) => void; private _workerPool: TranspileWorker[] = []; @@ -155,9 +157,33 @@ export class Transpiler { constructor( logFn: (topic: string, message: string) => void, private readonly _onError: (err: any) => void, + configFilePath: string, private readonly _cmdLine: ts.ParsedCommandLine ) { logFn('Transpile', `will use ${Transpiler.P} transpile worker`); + + + // very complicated logic to re-use TS internal functions to know the output path + // given a TS input path and its config + type InternalTsApi = typeof ts & { + getOutputFileNames(commandLine: ts.ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[]; + }; + this._getOutputFileName = (file) => { + if (!_cmdLine.options.configFilePath) { + // this is needed for the INTERNAL getOutputFileNames-call below... + _cmdLine.options.configFilePath = configFilePath; + } + const isDts = file.endsWith('.d.ts'); + if (isDts) { + file = file.slice(0, -5) + '.ts'; + _cmdLine.fileNames.push(file); + } + const outfile = (ts).getOutputFileNames(_cmdLine, file, true)[0]; + if (isDts) { + _cmdLine.fileNames.pop(); + } + return outfile; + }; } async join() { @@ -195,7 +221,7 @@ export class Transpiler { // kinda LAZYily create workers if (this._workerPool.length === 0) { for (let i = 0; i < Transpiler.P; i++) { - this._workerPool.push(new TranspileWorker(file => this._tsApiInternalOutfileName.getForInfile(file))); + this._workerPool.push(new TranspileWorker(file => this._getOutputFileName(file))); } } @@ -237,35 +263,6 @@ export class Transpiler { this._allJobs.push(job); } } - - private _tsApiInternalOutfileName = new class { - - getForInfile: (file: string) => string; - - constructor(parsedCmd: ts.ParsedCommandLine) { - - type InternalTsHost = { - getCompilerOptions(): ts.CompilerOptions; - getCurrentDirectory(): string; - getCommonSourceDirectory(): string; - getCanonicalFileName(file: string): string; - }; - type InternalTsApi = { getOwnEmitOutputFilePath(fileName: string, host: InternalTsHost, extension: string): string } & typeof ts; - - const host = ts.createCompilerHost(parsedCmd.options); - const program = ts.createProgram({ options: parsedCmd.options, rootNames: parsedCmd.fileNames, host }); - const emitHost: InternalTsHost = { - getCompilerOptions: () => parsedCmd.options, - getCurrentDirectory: () => host.getCurrentDirectory(), - getCanonicalFileName: file => host.getCanonicalFileName(file), - getCommonSourceDirectory: () => (program).getCommonSourceDirectory() - }; - - this.getForInfile = file => { - return (ts).getOwnEmitOutputFilePath(file, emitHost, '.js'); - }; - } - }(this._cmdLine); } function _isDefaultEmpty(src: string): boolean {