From d0be59017d7ade561862030466baecee19bf94af Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:38:26 -0400 Subject: [PATCH 1/2] refactor(@angular/build): dynamically load @babel/core in transformer worker By default, JavaScript transformations use the native OXC engine for Angular linking and advanced optimizations. The Babel-based linker is only utilized when the NG_BUILD_BABEL_LINKER environment variable is explicitly enabled. Previously, transformAsync was imported statically at the top level of javascript-transformer-worker.ts, causing Node.js to eagerly evaluate @babel/core and all its transitive dependencies on startup across every Piscina worker thread. Importing @babel/core dynamically only when the Babel linker fallback is active reduces worker thread startup latency and eliminates unnecessary worker idle memory overhead on standard builds. --- .../esbuild/javascript-transformer-worker.ts | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts index f2ec7eccce6d..99ef235f3279 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts @@ -7,7 +7,7 @@ */ import remapping, { type DecodedSourceMap, type EncodedSourceMap } from '@ampproject/remapping'; -import { type PluginItem, transformAsync } from '@babel/core'; +import type { PluginItem } from '@babel/core'; import { createRequire } from 'node:module'; import { workerData } from 'node:worker_threads'; import Piscina from 'piscina'; @@ -42,6 +42,16 @@ const { jit = false, } = (workerData || {}) as Partial; +let babelLinkerDeps: + | Promise< + [ + typeof import('@angular/compiler-cli/linker/babel'), + typeof import('@angular/compiler-cli'), + typeof import('@babel/core'), + ] + > + | undefined; + const textDecoder = new TextDecoder(); const textEncoder = new TextEncoder(); @@ -170,8 +180,13 @@ async function transformJavaScriptImpl( } if (shouldLink && useBabelLinker) { - const { createEs2015LinkerPlugin } = await import('@angular/compiler-cli/linker/babel'); - const { ConsoleLogger, LogLevel } = await import('@angular/compiler-cli'); + babelLinkerDeps ??= Promise.all([ + import('@angular/compiler-cli/linker/babel'), + import('@angular/compiler-cli'), + import('@babel/core'), + ]); + const [{ createEs2015LinkerPlugin }, { ConsoleLogger, LogLevel }, { transformAsync }] = + await babelLinkerDeps; const result = await transformAsync(code, { filename, From 33b6676fc50b4f2cc3c01e3a6a6c05c7ba5c54e9 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:39:21 -0400 Subject: [PATCH 2/2] refactor(@angular/build): use boundary resolution for sourcemap generation in oxc transform Generating high-resolution sourcemap tokens for every character with hires: true produces substantially larger intermediate decoded mappings and increases peak memory consumption during sourcemap remapping. Using hires: 'boundary' generates tokens only at identifier and word boundaries. This significantly reduces decoded sourcemap memory footprint and remapping time while retaining full debugging accuracy. --- packages/angular/build/src/tools/oxc/oxc-transform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/oxc/oxc-transform.ts b/packages/angular/build/src/tools/oxc/oxc-transform.ts index 0ebbc04ec1e5..e4f60ff83cb2 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform.ts @@ -737,7 +737,7 @@ export function transform(filename: string, code: string, options: OxcTransformO let map: DecodedSourceMap | undefined; if (options.sourcemap) { - const rawMap = source.generateDecodedMap({ hires: true, source: filename }); + const rawMap = source.generateDecodedMap({ hires: 'boundary', source: filename }); map = { ...rawMap, version: 3 }; }