From 3c2005cdeaf7d5234e73bc313d9730b053c04ff3 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:15:43 -0400 Subject: [PATCH] fix(@angular/build): correct JS/TS file paths when running under Bazel The compiler plugin now rewrites Bazel file paths if they were resolved outside of the execution root. This behavior is only used if Bazel environment variables are present. --- .../tools/esbuild/angular/compiler-plugin.ts | 9 ++++-- .../esbuild/angular/rewrite-bazel-paths.ts | 30 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/angular/rewrite-bazel-paths.ts diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index f56e6c6c3119..78b395058516 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -29,6 +29,7 @@ import { SharedTSCompilationState, getSharedCompilationState } from './compilati import { ComponentStylesheetBundler } from './component-stylesheets'; import { FileReferenceTracker } from './file-reference-tracker'; import { setupJitPluginCallbacks } from './jit-plugin-callbacks'; +import { rewriteForBazel } from './rewrite-bazel-paths'; import { SourceFileCache } from './source-file-cache'; export interface CompilerPluginOptions { @@ -411,8 +412,8 @@ export function createCompilerPlugin( }); build.onLoad({ filter: /\.[cm]?[jt]sx?$/ }, async (args) => { - const request = path.normalize( - pluginOptions.fileReplacements?.[path.normalize(args.path)] ?? args.path, + const request = rewriteForBazel( + path.normalize(pluginOptions.fileReplacements?.[path.normalize(args.path)] ?? args.path), ); const isJS = /\.[cm]?js$/.test(request); @@ -478,13 +479,14 @@ export function createCompilerPlugin( return { contents, loader, + resolveDir: path.dirname(request), }; }); build.onLoad( { filter: /\.[cm]?js$/ }, createCachedLoad(pluginOptions.loadResultCache, async (args) => { - let request = args.path; + let request = rewriteForBazel(args.path); if (pluginOptions.fileReplacements) { const replacement = pluginOptions.fileReplacements[path.normalize(args.path)]; if (replacement) { @@ -505,6 +507,7 @@ export function createCompilerPlugin( return { contents, loader: 'js', + resolveDir: path.dirname(request), watchFiles: request !== args.path ? [request] : undefined, }; }, diff --git a/packages/angular/build/src/tools/esbuild/angular/rewrite-bazel-paths.ts b/packages/angular/build/src/tools/esbuild/angular/rewrite-bazel-paths.ts new file mode 100644 index 000000000000..8a6fb6aa82a4 --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/angular/rewrite-bazel-paths.ts @@ -0,0 +1,30 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { join, relative } from 'node:path'; + +const bazelBinDirectory = process.env['BAZEL_BINDIR']; +const bazelExecRoot = process.env['JS_BINARY__EXECROOT']; + +export function rewriteForBazel(path: string): string { + if (!bazelBinDirectory || !bazelExecRoot) { + return path; + } + + const fromExecRoot = relative(bazelExecRoot, path); + if (!fromExecRoot.startsWith('..')) { + return path; + } + + const fromBinDirectory = relative(bazelBinDirectory, path); + if (fromBinDirectory.startsWith('..')) { + return path; + } + + return join(bazelExecRoot, fromBinDirectory); +}