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...
parent
4b48304259
commit
b942d2ea65
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue