Skip to content

Commit 3d00c76

Browse files
authored
fix(@angular/build): resolve library bundle sourcemap sources relative to output directory
Configure `cwd` and `sourcemapPathTransform` when generating FESM and declaration bundles in the library builder so that emitted sourcemap `sources` entries are computed relative to the actual output directory.
1 parent 5ffed3f commit 3d00c76

3 files changed

Lines changed: 38 additions & 16 deletions

File tree

‎packages/angular/build/src/builders/library/pipeline/bundler.ts‎

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -292,24 +292,35 @@ function processRolldownOutput(output: RolldownOutput['output'], dir: string): M
292292
*
293293
* @param input Map of bundle names to virtual entry file paths.
294294
* @param plugins Rolldown plugins to use during bundling.
295-
* @param preserveSymlinks Whether to preserve symlinks during module resolution.
296295
* @param extension Output file extension ('mjs' or 'd.ts').
297-
* @param sourcemap Whether to emit sourcemaps.
298-
* @param findEntryPoint Lookup function to resolve chunk entry point ownership.
296+
* @param options The normalized library options.
299297
* @returns A promise resolving to the multi-bundle output.
300298
*/
301299
async function executeMultiBundle(
302300
input: Record<string, string>,
303301
plugins: RolldownPluginOption[],
304-
preserveSymlinks: boolean,
305302
extension: 'mjs' | 'd.ts',
306-
sourcemap: boolean,
303+
options: NormalizedLibraryOptions,
307304
): Promise<MultiBundleOutput> {
305+
const { workspaceRoot, preserveSymlinks, declarationMap, outputPath } = options;
308306
const isDts = extension === 'd.ts';
309-
const dir = isDts ? TYPES_OUTPUT_DIR : FESM_OUTPUT_DIR;
307+
308+
let sourcemap: boolean;
309+
let dir: string;
310+
311+
if (isDts) {
312+
dir = TYPES_OUTPUT_DIR;
313+
sourcemap = declarationMap;
314+
} else {
315+
dir = FESM_OUTPUT_DIR;
316+
// FESM (.mjs) sourcemaps are always enabled.
317+
sourcemap = true;
318+
}
319+
310320
const bundle = await rolldown({
311321
context: 'this',
312322
input,
323+
cwd: workspaceRoot,
313324
plugins,
314325
treeshake: false,
315326
resolve: { symlinks: !preserveSymlinks },
@@ -322,7 +333,7 @@ async function executeMultiBundle(
322333
try {
323334
const { output } = await bundle.generate({
324335
format: 'es',
325-
dir,
336+
dir: path.join(outputPath, dir),
326337
entryFileNames: `[name].${extension}`,
327338
chunkFileNames: `[name]-[hash].${extension}`,
328339
sourcemap,
@@ -356,9 +367,8 @@ async function bundleAllEsm(
356367
return executeMultiBundle(
357368
resolveEntryInputMap(entryPoints, false),
358369
[createMemoryFileLoaderPlugin(esmFiles, ESM_EXTENSIONS, true)],
359-
options.preserveSymlinks,
360370
'mjs',
361-
true,
371+
options,
362372
);
363373
}
364374

@@ -389,10 +399,13 @@ async function bundleAllDts(
389399
dtsInput: true,
390400
tsconfig: false,
391401
sourcemap: dtsSourcemap,
402+
generator: 'oxc',
392403
});
404+
393405
const dtsPlugins = rawDtsPlugins.filter(
394406
(plugin) => plugin.name !== 'rolldown-plugin-dts:resolver',
395407
);
408+
396409
assert(
397410
dtsPlugins.length < rawDtsPlugins.length,
398411
'Expected "rolldown-plugin-dts:resolver" plugin to be present in rolldown-plugin-dts.',
@@ -401,8 +414,7 @@ async function bundleAllDts(
401414
return executeMultiBundle(
402415
resolveEntryInputMap(entryPoints, true),
403416
[createMemoryFileLoaderPlugin(dtsFiles, DTS_EXTENSIONS, dtsSourcemap), ...dtsPlugins],
404-
options.preserveSymlinks,
405417
'd.ts',
406-
dtsSourcemap,
418+
options,
407419
);
408420
}

‎packages/angular/build/src/builders/library/tests/behavior/build_spec.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9+
import { join } from 'node:path';
910
import { executeLibraryBuilder } from '../../builder';
1011
import { BASE_OPTIONS, LIBRARY_BUILDER_INFO, describeLibraryBuilder } from '../setup';
1112

@@ -21,11 +22,15 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) =>
2122
expect(result?.success).toBeTrue();
2223

2324
harness.expectFile('dist/lib/fesm2022/lib.mjs').toExist();
24-
expect(harness.hasFile('dist/lib/fesm2022/lib.mjs')).toBeTrue();
2525
const fesmContent = harness.readFile('dist/lib/fesm2022/lib.mjs');
2626
expect(fesmContent).toContain('LibComponent');
2727
expect(fesmContent).toContain('ɵcmp');
2828

29+
harness.expectFile('dist/lib/fesm2022/lib.mjs.map').toExist();
30+
const fesmMap = JSON.parse(harness.readFile('dist/lib/fesm2022/lib.mjs.map'));
31+
expect(fesmMap.sources).toContain('../../../projects/lib/src/lib/lib.component.ts');
32+
harness.expectFile(join('dist/lib/fesm2022', fesmMap.sources[0])).toExist();
33+
2934
harness.expectFile('dist/lib/types/lib.d.ts').toExist();
3035
const dtsContent = harness.readFile('dist/lib/types/lib.d.ts');
3136
expect(dtsContent).toContain('LibComponent');

‎packages/angular/build/src/builders/library/tests/options/declaration-map_spec.ts‎

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

99
import { executeLibraryBuilder } from '../../builder';
1010
import { BASE_OPTIONS, LIBRARY_BUILDER_INFO, describeLibraryBuilder } from '../setup';
11+
import { join } from 'node:path';
1112

1213
describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => {
1314
describe('Option: "declarationMap"', () => {
@@ -20,9 +21,9 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) =>
2021
expect(result?.success).toBeTrue();
2122

2223
// FESM sourcemaps are always enabled
23-
expect(harness.hasFile('dist/lib/fesm2022/lib.mjs.map')).toBeTrue();
24+
harness.expectFile('dist/lib/fesm2022/lib.mjs.map').toExist();
2425
// DTS sourcemaps are disabled by default
25-
expect(harness.hasFile('dist/lib/types/lib.d.ts.map')).toBeFalse();
26+
harness.expectFile('dist/lib/types/lib.d.ts.map').toNotExist();
2627
});
2728

2829
it('should emit declaration sourcemaps when declarationMap is true', async () => {
@@ -35,9 +36,13 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) =>
3536
expect(result?.success).toBeTrue();
3637

3738
// FESM sourcemaps are always enabled
38-
expect(harness.hasFile('dist/lib/fesm2022/lib.mjs.map')).toBeTrue();
39+
harness.expectFile('dist/lib/fesm2022/lib.mjs.map').toExist();
40+
3941
// DTS sourcemaps should be generated
40-
expect(harness.hasFile('dist/lib/types/lib.d.ts.map')).toBeTrue();
42+
harness.expectFile('dist/lib/types/lib.d.ts.map').toExist();
43+
const dtsMap = JSON.parse(harness.readFile('dist/lib/types/lib.d.ts.map'));
44+
expect(dtsMap.sources).toContain('../../../projects/lib/src/lib/lib.component.ts');
45+
harness.expectFile(join('dist/lib/types', dtsMap.sources[0])).toExist();
4146
});
4247
});
4348
});

0 commit comments

Comments
 (0)