Skip to content

Commit 72e820e

Browse files
alan-agius4dgp1130
authored andcommitted
fix(@angular-devkit/build-angular): better handle Windows paths in esbuild experimental builder
With this change we handle several esbuild path issues in Windows. Closes #23154 (cherry picked from commit 4325995)
1 parent 142da46 commit 72e820e

File tree

3 files changed

+24
-12
lines changed

3 files changed

+24
-12
lines changed

packages/angular_devkit/build_angular/src/builders/browser-esbuild/esbuild.ts

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import {
1616
build,
1717
formatMessages,
1818
} from 'esbuild';
19+
import { resolve } from 'path';
20+
21+
/** Default outdir setting for esbuild. */
22+
export const DEFAULT_OUTDIR = resolve('/virtual-output');
1923

2024
/**
2125
* Determines if an unknown value is an esbuild BuildFailure error object thrown by esbuild.

packages/angular_devkit/build_angular/src/builders/browser-esbuild/index.ts

+17-10
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { getIndexInputFile, getIndexOutputFile } from '../../utils/webpack-brows
2020
import { resolveGlobalStyles } from '../../webpack/configs';
2121
import { Schema as BrowserBuilderOptions, SourceMapClass } from '../browser/schema';
2222
import { createCompilerPlugin } from './compiler-plugin';
23-
import { bundle, logMessages } from './esbuild';
23+
import { DEFAULT_OUTDIR, bundle, logMessages } from './esbuild';
2424
import { logExperimentalWarnings } from './experimental-warnings';
2525
import { normalizeOptions } from './options';
2626
import { bundleStylesheetText } from './stylesheets';
@@ -116,11 +116,13 @@ export async function execute(
116116
// Entries in the metafile are relative to the `absWorkingDir` option which is set to the workspaceRoot
117117
const relativeFilePath = path.relative(workspaceRoot, outputFile.path);
118118
const entryPoint = result.metafile?.outputs[relativeFilePath]?.entryPoint;
119+
120+
outputFile.path = path.relative(DEFAULT_OUTDIR, outputFile.path);
121+
119122
if (entryPoint) {
120123
// An entryPoint value indicates an initial file
121124
initialFiles.push({
122-
// Remove leading directory separator
123-
file: outputFile.path.slice(1),
125+
file: outputFile.path,
124126
name: entryPointNameLookup.get(entryPoint) ?? '',
125127
extension: path.extname(outputFile.path),
126128
});
@@ -147,7 +149,9 @@ export async function execute(
147149
!!options.preserveSymlinks,
148150
);
149151
for (const [name, files] of Object.entries(stylesheetEntrypoints)) {
150-
const virtualEntryData = files.map((file) => `@import '${file}';`).join('\n');
152+
const virtualEntryData = files
153+
.map((file) => `@import '${file.replace(/\\/g, '/')}';`)
154+
.join('\n');
151155
const sheetResult = await bundleStylesheetText(
152156
virtualEntryData,
153157
{ virtualName: `angular:style/global;${name}`, resolvePath: workspaceRoot },
@@ -172,7 +176,7 @@ export async function execute(
172176
// The virtual stylesheets will be named `stdin` by esbuild. This must be replaced
173177
// with the actual name of the global style and the leading directory separator must
174178
// also be removed to make the path relative.
175-
const sheetPath = sheetResult.path.replace('stdin', name).slice(1);
179+
const sheetPath = sheetResult.path.replace('stdin', name);
176180
outputFiles.push(createOutputFileFromText(sheetPath, sheetResult.contents));
177181
if (sheetResult.map) {
178182
outputFiles.push(createOutputFileFromText(sheetPath + '.map', sheetResult.map));
@@ -203,10 +207,13 @@ export async function execute(
203207
optimization: optimizationOptions,
204208
crossOrigin: options.crossOrigin,
205209
});
206-
indexHtmlGenerator.readAsset = async function (path: string): Promise<string> {
210+
211+
/** Virtual output path to support reading in-memory files. */
212+
const virtualOutputPath = '/';
213+
indexHtmlGenerator.readAsset = async function (filePath: string): Promise<string> {
207214
// Remove leading directory separator
208-
path = path.slice(1);
209-
const file = outputFiles.find((file) => file.path === path);
215+
const relativefilePath = path.relative(virtualOutputPath, filePath);
216+
const file = outputFiles.find((file) => file.path === relativefilePath);
210217
if (file) {
211218
return file.text;
212219
}
@@ -217,7 +224,7 @@ export async function execute(
217224
const { content, warnings, errors } = await indexHtmlGenerator.process({
218225
baseHref: options.baseHref,
219226
lang: undefined,
220-
outputPath: '/', // Virtual output path to support reading in-memory files
227+
outputPath: virtualOutputPath,
221228
files: initialFiles,
222229
});
223230

@@ -280,7 +287,7 @@ async function bundleCode(
280287
metafile: true,
281288
minify: optimizationOptions.scripts,
282289
pure: ['forwardRef'],
283-
outdir: '/',
290+
outdir: DEFAULT_OUTDIR,
284291
sourcemap: sourcemapOptions.scripts && (sourcemapOptions.hidden ? 'external' : true),
285292
splitting: true,
286293
tsconfig,

packages/angular_devkit/build_angular/src/builders/browser-esbuild/stylesheets.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import type { BuildOptions, OutputFile } from 'esbuild';
1010
import * as path from 'path';
11-
import { bundle } from './esbuild';
11+
import { DEFAULT_OUTDIR, bundle } from './esbuild';
1212

1313
export interface BundleStylesheetOptions {
1414
workspaceRoot?: string;
@@ -32,7 +32,7 @@ async function bundleStylesheet(
3232
logLevel: 'silent',
3333
minify: options.optimization,
3434
sourcemap: options.sourcemap,
35-
outdir: '/',
35+
outdir: DEFAULT_OUTDIR,
3636
write: false,
3737
platform: 'browser',
3838
preserveSymlinks: options.preserveSymlinks,
@@ -50,6 +50,7 @@ async function bundleStylesheet(
5050
const resourceFiles: OutputFile[] = [];
5151
if (result.outputFiles) {
5252
for (const outputFile of result.outputFiles) {
53+
outputFile.path = path.relative(DEFAULT_OUTDIR, outputFile.path);
5354
const filename = path.basename(outputFile.path);
5455
if (filename.endsWith('.css')) {
5556
outputPath = outputFile.path;

0 commit comments

Comments
 (0)