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...

pull/152991/head
Johannes 2022-06-23 16:20:21 +02:00
parent 4b48304259
commit b942d2ea65
No known key found for this signature in database
GPG Key ID: 6DEF802A22264FCA
4 changed files with 47 additions and 49 deletions

View File

@ -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 {

View File

@ -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 = <any>(() => createTranspileStream(transpiler));
} else {
const _builder = builder.createTypeScriptBuilder({ logFn }, projectPath, cmdLine);

View File

@ -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);

View File

@ -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 = (<InternalTsApi>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: () => (<any>program).getCommonSourceDirectory()
};
this.getForInfile = file => {
return (<InternalTsApi>ts).getOwnEmitOutputFilePath(file, emitHost, '.js');
};
}
}(this._cmdLine);
}
function _isDefaultEmpty(src: string): boolean {