add esbuild transpiler for fast CI
This commit is contained in:
Родитель
96f0082842
Коммит
c1fb7325bd
|
@ -14,8 +14,8 @@ const path_1 = require("path");
|
|||
const utils_1 = require("./utils");
|
||||
const fs_1 = require("fs");
|
||||
const log = require("fancy-log");
|
||||
const colors = require("ansi-colors");
|
||||
const transpiler_1 = require("./transpiler");
|
||||
const colors = require("ansi-colors");
|
||||
class EmptyDuplex extends stream_1.Duplex {
|
||||
_write(_chunk, _encoding, callback) { callback(); }
|
||||
_read() { this.push(null); }
|
||||
|
@ -97,7 +97,7 @@ function create(projectPath, existingOptions, config, onError = _defaultOnError)
|
|||
if (config.transpileOnly) {
|
||||
const transpiler = !config.transpileWithSwc
|
||||
? new transpiler_1.TscTranspiler(logFn, printDiagnostic, projectPath, cmdLine)
|
||||
: new transpiler_1.SwcTranspiler(logFn, printDiagnostic, projectPath, cmdLine);
|
||||
: new transpiler_1.ESBuildTranspiler(logFn, printDiagnostic, projectPath, cmdLine);
|
||||
result = (() => createTranspileStream(transpiler));
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -12,8 +12,8 @@ import { dirname } from 'path';
|
|||
import { strings } from './utils';
|
||||
import { readFileSync, statSync } from 'fs';
|
||||
import * as log from 'fancy-log';
|
||||
import { ESBuildTranspiler, ITranspiler, TscTranspiler } from './transpiler';
|
||||
import colors = require('ansi-colors');
|
||||
import { ITranspiler, SwcTranspiler, TscTranspiler } from './transpiler';
|
||||
|
||||
export interface IncrementalCompiler {
|
||||
(token?: any): Readable & Writable;
|
||||
|
@ -130,7 +130,7 @@ export function create(
|
|||
if (config.transpileOnly) {
|
||||
const transpiler = !config.transpileWithSwc
|
||||
? new TscTranspiler(logFn, printDiagnostic, projectPath, cmdLine)
|
||||
: new SwcTranspiler(logFn, printDiagnostic, projectPath, cmdLine);
|
||||
: new ESBuildTranspiler(logFn, printDiagnostic, projectPath, cmdLine);
|
||||
result = <any>(() => createTranspileStream(transpiler));
|
||||
} else {
|
||||
const _builder = builder.createTypeScriptBuilder({ logFn }, projectPath, cmdLine);
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SwcTranspiler = exports.TscTranspiler = void 0;
|
||||
exports.SwcTranspiler = exports.ESBuildTranspiler = exports.TscTranspiler = void 0;
|
||||
const swc = require("@swc/core");
|
||||
const esbuild = require("esbuild");
|
||||
const ts = require("typescript");
|
||||
const threads = require("node:worker_threads");
|
||||
const Vinyl = require("vinyl");
|
||||
|
@ -224,6 +225,52 @@ class TscTranspiler {
|
|||
}
|
||||
}
|
||||
exports.TscTranspiler = TscTranspiler;
|
||||
class ESBuildTranspiler {
|
||||
_logFn;
|
||||
_onError;
|
||||
_cmdLine;
|
||||
_outputFileNames;
|
||||
_jobs = [];
|
||||
onOutfile;
|
||||
constructor(_logFn, _onError, configFilePath, _cmdLine) {
|
||||
this._logFn = _logFn;
|
||||
this._onError = _onError;
|
||||
this._cmdLine = _cmdLine;
|
||||
_logFn('Transpile', `will use ESBuild to transpile source files`);
|
||||
this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath);
|
||||
}
|
||||
async join() {
|
||||
const jobs = this._jobs.slice();
|
||||
this._jobs.length = 0;
|
||||
await Promise.allSettled(jobs);
|
||||
}
|
||||
transpile(file) {
|
||||
if (!(file.contents instanceof Buffer)) {
|
||||
throw Error('file.contents must be a Buffer');
|
||||
}
|
||||
const t1 = Date.now();
|
||||
this._jobs.push(esbuild.transform(file.contents, {
|
||||
target: ['es2022'],
|
||||
loader: 'ts',
|
||||
tsconfigRaw: JSON.stringify({ compilerOptions: this._cmdLine.options }),
|
||||
supported: {
|
||||
'class-static-blocks': false // SEE https://github.com/evanw/esbuild/issues/3823
|
||||
}
|
||||
}).then(result => {
|
||||
const outBase = this._cmdLine.options.outDir ?? file.base;
|
||||
const outPath = this._outputFileNames.getOutputFileName(file.path);
|
||||
this.onOutfile(new Vinyl({
|
||||
path: outPath,
|
||||
base: outBase,
|
||||
contents: Buffer.from(result.code),
|
||||
}));
|
||||
this._logFn('Transpile', `esbuild took ${Date.now() - t1}ms for ${file.path}`);
|
||||
}).catch(err => {
|
||||
this._onError(err);
|
||||
}));
|
||||
}
|
||||
}
|
||||
exports.ESBuildTranspiler = ESBuildTranspiler;
|
||||
function _isDefaultEmpty(src) {
|
||||
return src
|
||||
.replace('"use strict";', '')
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as swc from '@swc/core';
|
||||
import * as esbuild from 'esbuild';
|
||||
import * as ts from 'typescript';
|
||||
import * as threads from 'node:worker_threads';
|
||||
import * as Vinyl from 'vinyl';
|
||||
|
@ -291,6 +292,60 @@ export class TscTranspiler implements ITranspiler {
|
|||
}
|
||||
}
|
||||
|
||||
export class ESBuildTranspiler implements ITranspiler {
|
||||
|
||||
private readonly _outputFileNames: OutputFileNameOracle;
|
||||
private _jobs: Promise<any>[] = [];
|
||||
|
||||
onOutfile?: ((file: Vinyl) => void) | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly _logFn: (topic: string, message: string) => void,
|
||||
private readonly _onError: (err: any) => void,
|
||||
configFilePath: string,
|
||||
private readonly _cmdLine: ts.ParsedCommandLine
|
||||
) {
|
||||
_logFn('Transpile', `will use ESBuild to transpile source files`);
|
||||
this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath);
|
||||
}
|
||||
|
||||
async join(): Promise<void> {
|
||||
const jobs = this._jobs.slice();
|
||||
this._jobs.length = 0;
|
||||
await Promise.allSettled(jobs);
|
||||
}
|
||||
|
||||
transpile(file: Vinyl): void {
|
||||
if (!(file.contents instanceof Buffer)) {
|
||||
throw Error('file.contents must be a Buffer');
|
||||
}
|
||||
const t1 = Date.now();
|
||||
this._jobs.push(esbuild.transform(file.contents, {
|
||||
target: ['es2022'],
|
||||
loader: 'ts',
|
||||
tsconfigRaw: JSON.stringify({ compilerOptions: this._cmdLine.options }),
|
||||
supported: {
|
||||
'class-static-blocks': false // SEE https://github.com/evanw/esbuild/issues/3823
|
||||
}
|
||||
}).then(result => {
|
||||
|
||||
const outBase = this._cmdLine.options.outDir ?? file.base;
|
||||
const outPath = this._outputFileNames.getOutputFileName(file.path);
|
||||
|
||||
this.onOutfile!(new Vinyl({
|
||||
path: outPath,
|
||||
base: outBase,
|
||||
contents: Buffer.from(result.code),
|
||||
}));
|
||||
|
||||
this._logFn('Transpile', `esbuild took ${Date.now() - t1}ms for ${file.path}`);
|
||||
|
||||
}).catch(err => {
|
||||
this._onError(err);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
function _isDefaultEmpty(src: string): boolean {
|
||||
return src
|
||||
.replace('"use strict";', '')
|
||||
|
|
Загрузка…
Ссылка в новой задаче