Skip to content

Commit 88eb30c

Browse files
committed
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 be574a4 commit 88eb30c

3 files changed

Lines changed: 39 additions & 15 deletions

File tree

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

Lines changed: 23 additions & 10 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+
const relativeOutputPath = path.posix.relative(outputPath, workspaceRoot);
308+
309+
let sourcemap: boolean;
310+
let dir: string;
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 },
@@ -326,6 +337,7 @@ async function executeMultiBundle(
326337
entryFileNames: `[name].${extension}`,
327338
chunkFileNames: `[name]-[hash].${extension}`,
328339
sourcemap,
340+
sourcemapPathTransform: (sourcePath) => path.posix.join(relativeOutputPath, sourcePath),
329341
hoistTransitiveImports: false,
330342
comments: { jsdoc: isDts, legal: true, annotation: true },
331343
});
@@ -356,9 +368,8 @@ async function bundleAllEsm(
356368
return executeMultiBundle(
357369
resolveEntryInputMap(entryPoints, false),
358370
[createMemoryFileLoaderPlugin(esmFiles, ESM_EXTENSIONS, true)],
359-
options.preserveSymlinks,
360371
'mjs',
361-
true,
372+
options,
362373
);
363374
}
364375

@@ -389,10 +400,13 @@ async function bundleAllDts(
389400
dtsInput: true,
390401
tsconfig: false,
391402
sourcemap: dtsSourcemap,
403+
generator: 'oxc',
392404
});
405+
393406
const dtsPlugins = rawDtsPlugins.filter(
394407
(plugin) => plugin.name !== 'rolldown-plugin-dts:resolver',
395408
);
409+
396410
assert(
397411
dtsPlugins.length < rawDtsPlugins.length,
398412
'Expected "rolldown-plugin-dts:resolver" plugin to be present in rolldown-plugin-dts.',
@@ -401,8 +415,7 @@ async function bundleAllDts(
401415
return executeMultiBundle(
402416
resolveEntryInputMap(entryPoints, true),
403417
[createMemoryFileLoaderPlugin(dtsFiles, DTS_EXTENSIONS, dtsSourcemap), ...dtsPlugins],
404-
options.preserveSymlinks,
405418
'd.ts',
406-
dtsSourcemap,
419+
options,
407420
);
408421
}

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

Lines changed: 7 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,16 @@ 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();
25+
harness.expectFile('dist/lib/fesm2022/lib.mjs').toExist();
2526
const fesmContent = harness.readFile('dist/lib/fesm2022/lib.mjs');
2627
expect(fesmContent).toContain('LibComponent');
2728
expect(fesmContent).toContain('ɵcmp');
2829

30+
harness.expectFile('dist/lib/fesm2022/lib.mjs.map').toExist();
31+
const fesmMap = JSON.parse(harness.readFile('dist/lib/fesm2022/lib.mjs.map'));
32+
expect(fesmMap.sources).toContain('../../../projects/lib/src/lib/lib.component.ts');
33+
harness.expectFile(join('dist/lib/fesm2022', fesmMap.sources[0])).toExist();
34+
2935
harness.expectFile('dist/lib/types/lib.d.ts').toExist();
3036
const dtsContent = harness.readFile('dist/lib/types/lib.d.ts');
3137
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)