diff --git a/packages/angular/build/src/builders/library/pipeline/bundler.ts b/packages/angular/build/src/builders/library/pipeline/bundler.ts index d04996ec7ac4..3f47b45548d6 100644 --- a/packages/angular/build/src/builders/library/pipeline/bundler.ts +++ b/packages/angular/build/src/builders/library/pipeline/bundler.ts @@ -292,24 +292,35 @@ function processRolldownOutput(output: RolldownOutput['output'], dir: string): M * * @param input Map of bundle names to virtual entry file paths. * @param plugins Rolldown plugins to use during bundling. - * @param preserveSymlinks Whether to preserve symlinks during module resolution. * @param extension Output file extension ('mjs' or 'd.ts'). - * @param sourcemap Whether to emit sourcemaps. - * @param findEntryPoint Lookup function to resolve chunk entry point ownership. + * @param options The normalized library options. * @returns A promise resolving to the multi-bundle output. */ async function executeMultiBundle( input: Record, plugins: RolldownPluginOption[], - preserveSymlinks: boolean, extension: 'mjs' | 'd.ts', - sourcemap: boolean, + options: NormalizedLibraryOptions, ): Promise { + const { workspaceRoot, preserveSymlinks, declarationMap, outputPath } = options; const isDts = extension === 'd.ts'; - const dir = isDts ? TYPES_OUTPUT_DIR : FESM_OUTPUT_DIR; + + let sourcemap: boolean; + let dir: string; + + if (isDts) { + dir = TYPES_OUTPUT_DIR; + sourcemap = declarationMap; + } else { + dir = FESM_OUTPUT_DIR; + // FESM (.mjs) sourcemaps are always enabled. + sourcemap = true; + } + const bundle = await rolldown({ context: 'this', input, + cwd: workspaceRoot, plugins, treeshake: false, resolve: { symlinks: !preserveSymlinks }, @@ -322,7 +333,7 @@ async function executeMultiBundle( try { const { output } = await bundle.generate({ format: 'es', - dir, + dir: path.join(outputPath, dir), entryFileNames: `[name].${extension}`, chunkFileNames: `[name]-[hash].${extension}`, sourcemap, @@ -356,9 +367,8 @@ async function bundleAllEsm( return executeMultiBundle( resolveEntryInputMap(entryPoints, false), [createMemoryFileLoaderPlugin(esmFiles, ESM_EXTENSIONS, true)], - options.preserveSymlinks, 'mjs', - true, + options, ); } @@ -389,10 +399,13 @@ async function bundleAllDts( dtsInput: true, tsconfig: false, sourcemap: dtsSourcemap, + generator: 'oxc', }); + const dtsPlugins = rawDtsPlugins.filter( (plugin) => plugin.name !== 'rolldown-plugin-dts:resolver', ); + assert( dtsPlugins.length < rawDtsPlugins.length, 'Expected "rolldown-plugin-dts:resolver" plugin to be present in rolldown-plugin-dts.', @@ -401,8 +414,7 @@ async function bundleAllDts( return executeMultiBundle( resolveEntryInputMap(entryPoints, true), [createMemoryFileLoaderPlugin(dtsFiles, DTS_EXTENSIONS, dtsSourcemap), ...dtsPlugins], - options.preserveSymlinks, 'd.ts', - dtsSourcemap, + options, ); } diff --git a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts index 4e817babf944..a7b3828cbbbc 100644 --- a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts +++ b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import { join } from 'node:path'; import { executeLibraryBuilder } from '../../builder'; import { BASE_OPTIONS, LIBRARY_BUILDER_INFO, describeLibraryBuilder } from '../setup'; @@ -21,11 +22,15 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => expect(result?.success).toBeTrue(); harness.expectFile('dist/lib/fesm2022/lib.mjs').toExist(); - expect(harness.hasFile('dist/lib/fesm2022/lib.mjs')).toBeTrue(); const fesmContent = harness.readFile('dist/lib/fesm2022/lib.mjs'); expect(fesmContent).toContain('LibComponent'); expect(fesmContent).toContain('ɵcmp'); + harness.expectFile('dist/lib/fesm2022/lib.mjs.map').toExist(); + const fesmMap = JSON.parse(harness.readFile('dist/lib/fesm2022/lib.mjs.map')); + expect(fesmMap.sources).toContain('../../../projects/lib/src/lib/lib.component.ts'); + harness.expectFile(join('dist/lib/fesm2022', fesmMap.sources[0])).toExist(); + harness.expectFile('dist/lib/types/lib.d.ts').toExist(); const dtsContent = harness.readFile('dist/lib/types/lib.d.ts'); expect(dtsContent).toContain('LibComponent'); diff --git a/packages/angular/build/src/builders/library/tests/options/declaration-map_spec.ts b/packages/angular/build/src/builders/library/tests/options/declaration-map_spec.ts index 6ff112ac3912..a37e2f0dd255 100644 --- a/packages/angular/build/src/builders/library/tests/options/declaration-map_spec.ts +++ b/packages/angular/build/src/builders/library/tests/options/declaration-map_spec.ts @@ -8,6 +8,7 @@ import { executeLibraryBuilder } from '../../builder'; import { BASE_OPTIONS, LIBRARY_BUILDER_INFO, describeLibraryBuilder } from '../setup'; +import { join } from 'node:path'; describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => { describe('Option: "declarationMap"', () => { @@ -20,9 +21,9 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => expect(result?.success).toBeTrue(); // FESM sourcemaps are always enabled - expect(harness.hasFile('dist/lib/fesm2022/lib.mjs.map')).toBeTrue(); + harness.expectFile('dist/lib/fesm2022/lib.mjs.map').toExist(); // DTS sourcemaps are disabled by default - expect(harness.hasFile('dist/lib/types/lib.d.ts.map')).toBeFalse(); + harness.expectFile('dist/lib/types/lib.d.ts.map').toNotExist(); }); it('should emit declaration sourcemaps when declarationMap is true', async () => { @@ -35,9 +36,13 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => expect(result?.success).toBeTrue(); // FESM sourcemaps are always enabled - expect(harness.hasFile('dist/lib/fesm2022/lib.mjs.map')).toBeTrue(); + harness.expectFile('dist/lib/fesm2022/lib.mjs.map').toExist(); + // DTS sourcemaps should be generated - expect(harness.hasFile('dist/lib/types/lib.d.ts.map')).toBeTrue(); + harness.expectFile('dist/lib/types/lib.d.ts.map').toExist(); + const dtsMap = JSON.parse(harness.readFile('dist/lib/types/lib.d.ts.map')); + expect(dtsMap.sources).toContain('../../../projects/lib/src/lib/lib.component.ts'); + harness.expectFile(join('dist/lib/types', dtsMap.sources[0])).toExist(); }); }); });