From d3c73e340a016fe8249c594e01d79c434eaac4f5 Mon Sep 17 00:00:00 2001 From: jdalton Date: Fri, 17 Apr 2026 16:31:33 -0400 Subject: [PATCH 1/2] chore(build): bump esbuild target to node25 Updates the hardcoded esbuild `target` in the two prod build configs (cli.mts and esbuild-utils.mts) from 'node18' to 'node25' so the output matches what we actually ship and run (see .node-version). No runtime behavior change; just unlocks the newer syntax lowering defaults in esbuild so the bundle doesn't carry transforms for language features that are already native in node 18+. --- packages/cli/.config/esbuild.cli.mts | 2 +- packages/cli/scripts/esbuild-utils.mts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/.config/esbuild.cli.mts b/packages/cli/.config/esbuild.cli.mts index af30ac0f6..b6bee6772 100644 --- a/packages/cli/.config/esbuild.cli.mts +++ b/packages/cli/.config/esbuild.cli.mts @@ -63,7 +63,7 @@ const config: BuildOptions = { bundle: true, outfile: path.join(rootPath, 'build/cli.js'), platform: 'node', - target: 'node18', + target: 'node25', format: 'cjs', logOverride: { 'commonjs-variable-in-esm': 'silent', diff --git a/packages/cli/scripts/esbuild-utils.mts b/packages/cli/scripts/esbuild-utils.mts index 1408ea32d..dc3ae3921 100644 --- a/packages/cli/scripts/esbuild-utils.mts +++ b/packages/cli/scripts/esbuild-utils.mts @@ -38,7 +38,7 @@ export function createIndexConfig({ entryPoint, outfile }: { entryPoint: string; platform: 'node', // Source maps off for entry point production build. sourcemap: false, - target: 'node18', + target: 'node25', // Define environment variables for inlining. define: { 'process.env.NODE_ENV': '"production"', From f9e298004ec2450074522bcdc29c433b0122d06d Mon Sep 17 00:00:00 2001 From: jdalton Date: Fri, 17 Apr 2026 16:52:14 -0400 Subject: [PATCH 2/2] chore(build): extract shared esbuild base config (DRY) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduces `createBaseConfig(inlinedEnvVars)` in esbuild-utils.mts that returns the settings every Socket CLI esbuild config needs to agree on: bundle, format, minify, platform, sourcemap, target, write, define: { 'process.env.NODE_ENV': '"production"', ...inlined } Both callers spread it and add their variant-specific fields: * `createIndexConfig` (index loader): banner + entry + output + env-var replacement plugin. * `esbuild.cli.mts` (main bundle): shebang+importMeta banner, extra `import.meta.url` define, `keepNames`, `loader`, `logOverride`, `metafile`, plugin stack. Before: the Node target and six other shared settings were duplicated between the two configs, so bumping something like `target: 'node25'` meant remembering to touch both files (and earlier PRs did miss exactly that pattern). No behavior change — diffed the build output before/after. --- packages/cli/.config/esbuild.cli.mts | 36 +++++++-------- packages/cli/scripts/esbuild-utils.mts | 62 ++++++++++++++++---------- 2 files changed, 53 insertions(+), 45 deletions(-) diff --git a/packages/cli/.config/esbuild.cli.mts b/packages/cli/.config/esbuild.cli.mts index b6bee6772..2d91f06bb 100644 --- a/packages/cli/.config/esbuild.cli.mts +++ b/packages/cli/.config/esbuild.cli.mts @@ -14,7 +14,7 @@ import { IMPORT_META_URL_BANNER } from 'build-infra/lib/esbuild-helpers' import { unicodeTransformPlugin } from 'build-infra/lib/esbuild-plugin-unicode-transform' import { - createDefineEntries, + createBaseConfig, envVarReplacementPlugin, getInlinedEnvVars, runBuild, @@ -58,33 +58,27 @@ function resolveSocketLibExternal(socketLibPath: string, packageName: string) { } +const baseConfig = createBaseConfig(inlinedEnvVars) + const config: BuildOptions = { + ...baseConfig, + banner: { + js: `#!/usr/bin/env node\n"use strict";\n${IMPORT_META_URL_BANNER.js}`, + }, + define: { + ...baseConfig.define, + 'import.meta.url': '__importMetaUrl', + }, entryPoints: [path.join(rootPath, 'src/cli-dispatch.mts')], - bundle: true, - outfile: path.join(rootPath, 'build/cli.js'), - platform: 'node', - target: 'node25', - format: 'cjs', + keepNames: true, + // .cs files used by node-gyp on Windows. + loader: { '.cs': 'empty' }, logOverride: { 'commonjs-variable-in-esm': 'silent', 'require-resolve-not-external': 'silent', }, - // .cs files used by node-gyp on Windows. - loader: { '.cs': 'empty' }, - sourcemap: false, - minify: false, - keepNames: true, - write: false, metafile: true, - define: { - 'process.env.NODE_ENV': '"production"', - 'import.meta.url': '__importMetaUrl', - ...createDefineEntries(inlinedEnvVars), - }, - banner: { - js: `#!/usr/bin/env node\n"use strict";\n${IMPORT_META_URL_BANNER.js}`, - }, - + outfile: path.join(rootPath, 'build/cli.js'), plugins: [ unicodeTransformPlugin(), // Environment variable replacement must run AFTER unicode transform. diff --git a/packages/cli/scripts/esbuild-utils.mts b/packages/cli/scripts/esbuild-utils.mts index dc3ae3921..8450a4f67 100644 --- a/packages/cli/scripts/esbuild-utils.mts +++ b/packages/cli/scripts/esbuild-utils.mts @@ -15,42 +15,56 @@ import { EnvironmentVariables } from './environment-variables.mts' const logger = getDefaultLogger() +/** + * Settings every Socket CLI esbuild config shares. + * + * Kept in one place so the target Node version, module format, minify + * default, etc. can't drift between the index loader and the main CLI + * bundle. Callers spread this and add variant-specific fields + * (entry points, output, banner, plugins, extra defines). + */ +export function createBaseConfig( + inlinedEnvVars: Record, +): BuildOptions { + return { + bundle: true, + define: { + 'process.env.NODE_ENV': '"production"', + ...createDefineEntries(inlinedEnvVars), + }, + format: 'cjs', + minify: false, + platform: 'node', + // We don't ship minified bundles and we don't ship sourcemaps for prod. + sourcemap: false, + target: 'node25', + // Plugin writes are handled by `runBuild` so every caller's env-var + // replacement can mutate output buffers before they hit disk. + write: false, + } +} + /** * Create a standard index loader config. - * @param {Object} options - Configuration options - * @param {string} options.entryPoint - Path to entry point file - * @param {string} options.outfile - Path to output file - * @returns {Object} esbuild configuration object */ -export function createIndexConfig({ entryPoint, outfile }: { entryPoint: string; outfile: string }) { - // Get inlined environment variables for build-time constant replacement. +export function createIndexConfig({ + entryPoint, + outfile, +}: { + entryPoint: string + outfile: string +}): BuildOptions { const inlinedEnvVars = getInlinedEnvVars() - const config: BuildOptions = { + return { + ...createBaseConfig(inlinedEnvVars), banner: { js: '#!/usr/bin/env node', }, - bundle: true, entryPoints: [entryPoint], - format: 'cjs', - minify: false, outfile, - platform: 'node', - // Source maps off for entry point production build. - sourcemap: false, - target: 'node25', - // Define environment variables for inlining. - define: { - 'process.env.NODE_ENV': '"production"', - ...createDefineEntries(inlinedEnvVars), - }, - // Add plugin for post-bundle env var replacement. plugins: [envVarReplacementPlugin(inlinedEnvVars)], - // Plugin needs to transform output. - write: false, } - - return config } /**