Skip to content

Commit 53dd929

Browse files
clydindgp1130
authored andcommitted
fix(@angular-devkit/build-angular): ensure esbuild builder sourcemap sources are relative to workspace
This change adjusts the virtual output directory of the configuration for the experimental esbuild-based browser application builder to be based on the workspace root. This allows esbuild to generate sourcemap source paths that are relative to the workspace root and that do not contain path information from outside the workspace root.
1 parent 357c45e commit 53dd929

File tree

5 files changed

+36
-13
lines changed

5 files changed

+36
-13
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ jobs:
221221
name: Execute CLI E2E Tests Subset with esbuild builder
222222
command: |
223223
mkdir /mnt/ramdisk/e2e-esbuild
224-
node ./tests/legacy-cli/run_e2e --nb-shards=${CIRCLE_NODE_TOTAL} --shard=${CIRCLE_NODE_INDEX} <<# parameters.snapshots >>--ng-snapshots<</ parameters.snapshots >> --esbuild --tmpdir=/mnt/ramdisk/e2e-esbuild --glob="{tests/basic/**,tests/build/prod-build.ts,tests/build/styles/scss.ts,tests/build/styles/include-paths.ts,tests/commands/add/add-pwa.ts}" --ignore="tests/basic/{environment,rebuild,serve,scripts-array}.ts"
224+
node ./tests/legacy-cli/run_e2e --nb-shards=${CIRCLE_NODE_TOTAL} --shard=${CIRCLE_NODE_INDEX} <<# parameters.snapshots >>--ng-snapshots<</ parameters.snapshots >> --esbuild --tmpdir=/mnt/ramdisk/e2e-esbuild --glob="{tests/basic/**,tests/build/prod-build.ts,tests/build/relative-sourcemap.ts,tests/build/styles/scss.ts,tests/build/styles/include-paths.ts,tests/commands/add/add-pwa.ts}" --ignore="tests/basic/{environment,rebuild,serve,scripts-array}.ts"
225225
- fail_fast
226226

227227
test-browsers:

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ 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');
2319

2420
/**
2521
* 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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { augmentAppWithServiceWorker } from '../../utils/service-worker';
2121
import { getIndexInputFile, getIndexOutputFile } from '../../utils/webpack-browser-config';
2222
import { resolveGlobalStyles } from '../../webpack/configs';
2323
import { createCompilerPlugin } from './compiler-plugin';
24-
import { DEFAULT_OUTDIR, bundle, logMessages } from './esbuild';
24+
import { bundle, logMessages } from './esbuild';
2525
import { logExperimentalWarnings } from './experimental-warnings';
2626
import { normalizeOptions } from './options';
2727
import { Schema as BrowserBuilderOptions, SourceMapClass } from './schema';
@@ -120,7 +120,7 @@ export async function buildEsbuildBrowser(
120120
const relativeFilePath = path.relative(workspaceRoot, outputFile.path);
121121
const entryPoint = result.metafile?.outputs[relativeFilePath]?.entryPoint;
122122

123-
outputFile.path = path.relative(DEFAULT_OUTDIR, outputFile.path);
123+
outputFile.path = relativeFilePath;
124124

125125
if (entryPoint) {
126126
// An entryPoint value indicates an initial file
@@ -159,6 +159,7 @@ export async function buildEsbuildBrowser(
159159
virtualEntryData,
160160
{ virtualName: `angular:style/global;${name}`, resolvePath: workspaceRoot },
161161
{
162+
workspaceRoot,
162163
optimization: !!optimizationOptions.styles.minify,
163164
sourcemap: !!sourcemapOptions.styles && (sourcemapOptions.hidden ? 'external' : true),
164165
outputNames: noInjectNames.includes(name) ? { media: outputNames.media } : outputNames,
@@ -309,7 +310,7 @@ async function bundleCode(
309310
metafile: true,
310311
minify: optimizationOptions.scripts,
311312
pure: ['forwardRef'],
312-
outdir: DEFAULT_OUTDIR,
313+
outdir: workspaceRoot,
313314
sourcemap: sourcemapOptions.scripts && (sourcemapOptions.hidden ? 'external' : true),
314315
splitting: true,
315316
tsconfig,

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88

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

1414
export interface BundleStylesheetOptions {
15-
workspaceRoot?: string;
15+
workspaceRoot: string;
1616
optimization: boolean;
1717
preserveSymlinks?: boolean;
1818
sourcemap: boolean | 'external' | 'inline';
@@ -34,7 +34,7 @@ async function bundleStylesheet(
3434
logLevel: 'silent',
3535
minify: options.optimization,
3636
sourcemap: options.sourcemap,
37-
outdir: DEFAULT_OUTDIR,
37+
outdir: options.workspaceRoot,
3838
write: false,
3939
platform: 'browser',
4040
preserveSymlinks: options.preserveSymlinks,
@@ -52,7 +52,7 @@ async function bundleStylesheet(
5252
const resourceFiles: OutputFile[] = [];
5353
if (result.outputFiles) {
5454
for (const outputFile of result.outputFiles) {
55-
outputFile.path = path.relative(DEFAULT_OUTDIR, outputFile.path);
55+
outputFile.path = path.relative(options.workspaceRoot, outputFile.path);
5656
const filename = path.basename(outputFile.path);
5757
if (filename.endsWith('.css')) {
5858
outputPath = outputFile.path;
Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,45 @@
11
import * as fs from 'fs';
22

33
import { isAbsolute } from 'path';
4+
import { getGlobalVariable } from '../../utils/env';
45
import { ng } from '../../utils/process';
6+
import { updateJsonFile } from '../../utils/project';
57

68
export default async function () {
79
// General secondary application project
810
await ng('generate', 'application', 'secondary-project', '--skip-install');
11+
// Setup esbuild builder if requested on the commandline
12+
const useEsbuildBuilder = !!getGlobalVariable('argv')['esbuild'];
13+
if (useEsbuildBuilder) {
14+
await updateJsonFile('angular.json', (json) => {
15+
json['projects']['secondary-project']['architect']['build']['builder'] =
16+
'@angular-devkit/build-angular:browser-esbuild';
17+
});
18+
}
19+
920
await ng('build', 'secondary-project', '--configuration=development');
1021

1122
await ng('build', '--output-hashing=none', '--source-map', '--configuration=development');
1223
const content = fs.readFileSync('./dist/secondary-project/main.js.map', 'utf8');
13-
const { sources } = JSON.parse(content);
24+
const { sources } = JSON.parse(content) as { sources: string[] };
25+
let mainFileFound = false;
1426
for (const source of sources) {
1527
if (isAbsolute(source)) {
1628
throw new Error(`Expected ${source} to be relative.`);
1729
}
30+
31+
if (source.endsWith('main.ts')) {
32+
mainFileFound = true;
33+
if (
34+
source !== 'projects/secondary-project/src/main.ts' &&
35+
source !== './projects/secondary-project/src/main.ts'
36+
) {
37+
throw new Error(`Expected main file ${source} to be relative to the workspace root.`);
38+
}
39+
}
40+
}
41+
42+
if (!mainFileFound) {
43+
throw new Error('Could not find the main file in the application sourcemap sources array.');
1844
}
1945
}

0 commit comments

Comments
 (0)