Pick up esbuild target from tsconfig files

This commit is contained in:
Matt Bierner
2025-10-30 08:53:24 -07:00
parent 4df8d67121
commit 883485b3b5
6 changed files with 80 additions and 6 deletions

View File

@@ -54,6 +54,7 @@ const esbuild_1 = __importDefault(require("esbuild"));
const gulp_sourcemaps_1 = __importDefault(require("gulp-sourcemaps"));
const fancy_log_1 = __importDefault(require("fancy-log"));
const ansi_colors_1 = __importDefault(require("ansi-colors"));
const tsconfig_1 = require("./tsconfig");
const REPO_ROOT_PATH = path_1.default.join(__dirname, '../..');
const DEFAULT_FILE_HEADER = [
'/*!--------------------------------------------------------',
@@ -63,6 +64,7 @@ const DEFAULT_FILE_HEADER = [
function bundleESMTask(opts) {
const resourcesStream = event_stream_1.default.through(); // this stream will contain the resources
const bundlesStream = event_stream_1.default.through(); // this stream will contain the bundled files
const target = getBuildTarget();
const entryPoints = opts.entryPoints.map(entryPoint => {
if (typeof entryPoint === 'string') {
return { name: path_1.default.parse(entryPoint).name };
@@ -125,7 +127,7 @@ function bundleESMTask(opts) {
format: 'esm',
sourcemap: 'external',
plugins: [contentsMapper, externalOverride],
target: ['es2022'],
target: [target],
loader: {
'.ttf': 'file',
'.svg': 'file',
@@ -185,6 +187,7 @@ function bundleTask(opts) {
}
function minifyTask(src, sourceMapBaseUrl) {
const sourceMappingURL = sourceMapBaseUrl ? ((f) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
const target = getBuildTarget();
return cb => {
const svgmin = require('gulp-svgmin');
const esbuildFilter = (0, gulp_filter_1.default)('**/*.{js,css}', { restore: true });
@@ -197,7 +200,7 @@ function minifyTask(src, sourceMapBaseUrl) {
outdir: '.',
packages: 'external', // "external all the things", see https://esbuild.github.io/api/#packages
platform: 'neutral', // makes esm
target: ['es2022'],
target: [target],
write: false,
}).then(res => {
const jsOrCSSFile = res.outputFiles.find(f => /\.(js|css)$/.test(f.path));
@@ -221,4 +224,8 @@ function minifyTask(src, sourceMapBaseUrl) {
}), gulp_1.default.dest(src + '-min'), (err) => cb(err));
};
}
function getBuildTarget() {
const tsconfigPath = path_1.default.join(REPO_ROOT_PATH, 'src', 'tsconfig.base.json');
return (0, tsconfig_1.getTargetStringFromTsConfig)(tsconfigPath);
}
//# sourceMappingURL=optimize.js.map

View File

@@ -15,6 +15,7 @@ import esbuild from 'esbuild';
import sourcemaps from 'gulp-sourcemaps';
import fancyLog from 'fancy-log';
import ansiColors from 'ansi-colors';
import { getTargetStringFromTsConfig } from './tsconfig';
declare module 'gulp-sourcemaps' {
interface WriteOptions {
@@ -64,6 +65,8 @@ function bundleESMTask(opts: IBundleESMTaskOpts): NodeJS.ReadWriteStream {
const resourcesStream = es.through(); // this stream will contain the resources
const bundlesStream = es.through(); // this stream will contain the bundled files
const target = getBuildTarget();
const entryPoints = opts.entryPoints.map(entryPoint => {
if (typeof entryPoint === 'string') {
return { name: path.parse(entryPoint).name };
@@ -137,7 +140,7 @@ function bundleESMTask(opts: IBundleESMTaskOpts): NodeJS.ReadWriteStream {
format: 'esm',
sourcemap: 'external',
plugins: [contentsMapper, externalOverride],
target: ['es2022'],
target: [target],
loader: {
'.ttf': 'file',
'.svg': 'file',
@@ -221,6 +224,7 @@ export function bundleTask(opts: IBundleESMTaskOpts): () => NodeJS.ReadWriteStre
export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) => void {
const sourceMappingURL = sourceMapBaseUrl ? ((f: any) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
const target = getBuildTarget();
return cb => {
const svgmin = require('gulp-svgmin') as typeof import('gulp-svgmin');
@@ -240,7 +244,7 @@ export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) =>
outdir: '.',
packages: 'external', // "external all the things", see https://esbuild.github.io/api/#packages
platform: 'neutral', // makes esm
target: ['es2022'],
target: [target],
write: false,
}).then(res => {
const jsOrCSSFile = res.outputFiles.find(f => /\.(js|css)$/.test(f.path))!;
@@ -272,3 +276,9 @@ export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) =>
(err: any) => cb(err));
};
}
function getBuildTarget() {
const tsconfigPath = path.join(REPO_ROOT_PATH, 'src', 'tsconfig.base.json');
return getTargetStringFromTsConfig(tsconfigPath);
}

View File

@@ -13,6 +13,7 @@ const typescript_1 = __importDefault(require("typescript"));
const node_worker_threads_1 = __importDefault(require("node:worker_threads"));
const vinyl_1 = __importDefault(require("vinyl"));
const node_os_1 = require("node:os");
const tsconfig_1 = require("../tsconfig");
function transpile(tsSrc, options) {
const isAmd = /\n(import|export)/m.test(tsSrc);
if (!isAmd && options.compilerOptions?.module === typescript_1.default.ModuleKind.AMD) {
@@ -240,8 +241,9 @@ class ESBuildTranspiler {
_logFn('Transpile', `will use ESBuild to transpile source files`);
this._outputFileNames = new OutputFileNameOracle(_cmdLine, configFilePath);
const isExtension = configFilePath.includes('extensions');
const target = (0, tsconfig_1.getTargetStringFromTsConfig)(configFilePath);
this._transformOpts = {
target: ['es2022'],
target: [target],
format: isExtension ? 'cjs' : 'esm',
platform: isExtension ? 'node' : undefined,
loader: 'ts',

View File

@@ -8,6 +8,7 @@ import ts from 'typescript';
import threads from 'node:worker_threads';
import Vinyl from 'vinyl';
import { cpus } from 'node:os';
import { getTargetStringFromTsConfig } from '../tsconfig';
interface TranspileReq {
readonly tsSrcs: string[];
@@ -311,8 +312,10 @@ export class ESBuildTranspiler implements ITranspiler {
const isExtension = configFilePath.includes('extensions');
const target = getTargetStringFromTsConfig(configFilePath);
this._transformOpts = {
target: ['es2022'],
target: [target],
format: isExtension ? 'cjs' : 'esm',
platform: isExtension ? 'node' : undefined,
loader: 'ts',

28
build/lib/tsconfig.js Normal file
View File

@@ -0,0 +1,28 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTargetStringFromTsConfig = getTargetStringFromTsConfig;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const posix_1 = require("path/posix");
const typescript_1 = __importDefault(require("typescript"));
/**
* Get the target (e.g. 'ES2024') from a tsconfig.json file.
*/
function getTargetStringFromTsConfig(configFilePath) {
const parsed = typescript_1.default.readConfigFile(configFilePath, typescript_1.default.sys.readFile);
if (parsed.error) {
throw new Error(`Cannot determine target from ${configFilePath}. TS error: ${parsed.error.messageText}`);
}
const cmdLine = typescript_1.default.parseJsonConfigFileContent(parsed.config, typescript_1.default.sys, (0, posix_1.dirname)(configFilePath), {});
const resolved = typeof cmdLine.options.target !== 'undefined' ? typescript_1.default.ScriptTarget[cmdLine.options.target] : undefined;
if (!resolved) {
throw new Error(`Could not resolve target in ${configFilePath}`);
}
return resolved;
}
//# sourceMappingURL=tsconfig.js.map

24
build/lib/tsconfig.ts Normal file
View File

@@ -0,0 +1,24 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { dirname } from 'path/posix';
import ts from 'typescript';
/**
* Get the target (e.g. 'ES2024') from a tsconfig.json file.
*/
export function getTargetStringFromTsConfig(configFilePath: string): string {
const parsed = ts.readConfigFile(configFilePath, ts.sys.readFile);
if (parsed.error) {
throw new Error(`Cannot determine target from ${configFilePath}. TS error: ${parsed.error.messageText}`);
}
const cmdLine = ts.parseJsonConfigFileContent(parsed.config, ts.sys, dirname(configFilePath), {});
const resolved = typeof cmdLine.options.target !== 'undefined' ? ts.ScriptTarget[cmdLine.options.target] : undefined;
if (!resolved) {
throw new Error(`Could not resolve target in ${configFilePath}`);
}
return resolved;
}