Skip to content

Commit 2c518a6

Browse files
authored
fix(@angular/build): enhance build logs and output location for library builder
Align library builder logs with the application builder format by logging: - `Library bundle generation complete. [X seconds] - <timestamp>` on build completion - `Output location: <outputPath>` for successful builds - `Watch mode enabled. Watching for file changes...` after initial build when watch mode is active
1 parent fb7efc8 commit 2c518a6

2 files changed

Lines changed: 72 additions & 12 deletions

File tree

‎packages/angular/build/src/builders/library/builder.ts‎

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,6 @@ export async function* executeLibraryBuilder(
120120
}
121121

122122
if (isWatchMode) {
123-
if (progress) {
124-
logger.info('Watch mode enabled. Watching for file changes...');
125-
}
126-
127123
const { setupWatcher } = await import('../../utils/watcher');
128124
watcher = await setupWatcher({
129125
workspaceRoot,
@@ -154,6 +150,11 @@ export async function* executeLibraryBuilder(
154150
watcher,
155151
buildAction,
156152
);
153+
154+
if (isWatchMode && progress) {
155+
logger.info('Watch mode enabled. Watching for file changes...');
156+
}
157+
157158
yield initialResult;
158159

159160
if (!isWatchMode || !watcher) {
@@ -192,11 +193,11 @@ async function executeBuild(
192193
buildAction: typeof import('./pipeline/build-action').buildAction,
193194
): Promise<BuilderOutput> {
194195
const startTime = process.hrtime.bigint();
195-
const { context, watchedCompilationFiles, isWatchMode } = actionContext;
196+
const { context, watchedCompilationFiles, isWatchMode, options } = actionContext;
196197

197198
try {
198199
await withProgress(message, () => buildAction(actionContext));
199-
logBuildResult(context.logger, startTime, true);
200+
logBuildResult(context.logger, startTime, true, options.outputPath);
200201
if (isWatchMode) {
201202
logCumulativeDurations();
202203
}
@@ -345,14 +346,23 @@ async function* runWatchLoop(
345346
/**
346347
* Logs the build completion time and status.
347348
*/
348-
function logBuildResult(logger: logging.LoggerApi, startTime: bigint, success: boolean): void {
349-
const durationMs = Number(process.hrtime.bigint() - startTime) / 1_000_000;
350-
const durationSec = (durationMs / 1000).toFixed(2);
349+
function logBuildResult(
350+
logger: logging.LoggerApi,
351+
startTime: bigint,
352+
success: boolean,
353+
outputPath?: string,
354+
): void {
355+
const buildTime = Number(process.hrtime.bigint() - startTime) / 10 ** 9;
356+
const message =
357+
`Library bundle generation ${success ? 'complete' : 'failed'}.` +
358+
` [${buildTime.toFixed(3)} seconds] - ${new Date().toISOString()}`;
351359

352360
if (success) {
353-
logger.info(`Build at: ${new Date().toISOString()} - Time: ${durationMs.toFixed(0)}ms`);
354-
logger.info(`Built Angular library in ${durationSec}s.`);
361+
logger.info(message);
362+
if (outputPath) {
363+
logger.info(`Output location: ${outputPath}\n`);
364+
}
355365
} else {
356-
logger.error(`Build failed after ${durationSec}s.`);
366+
logger.error(message);
357367
}
358368
}

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,5 +180,55 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) =>
180180
tslib: '^2.0.0',
181181
});
182182
});
183+
184+
it('should log completion and output location', async () => {
185+
harness.useTarget('build', {
186+
...BASE_OPTIONS,
187+
});
188+
189+
const { result, logs } = await harness.executeOnce();
190+
expect(result?.success).toBeTrue();
191+
expect(logs).toContain(
192+
jasmine.objectContaining({
193+
level: 'info',
194+
message: jasmine.stringMatching(
195+
/Library bundle generation complete\. \[\d+\.\d{3} seconds\] - \d{4}-\d{2}-\d{2}T/,
196+
),
197+
}),
198+
);
199+
expect(logs).toContain(
200+
jasmine.objectContaining({
201+
level: 'info',
202+
message: jasmine.stringMatching(/Output location: .*dist[/\\]lib/),
203+
}),
204+
);
205+
});
206+
207+
it('should log failure on build error', async () => {
208+
await harness.writeFile(
209+
'projects/lib/src/public-api.ts',
210+
`export const title: number = 'invalid type';`,
211+
);
212+
213+
harness.useTarget('build', {
214+
...BASE_OPTIONS,
215+
});
216+
217+
const { result, logs } = await harness.executeOnce({ outputLogsOnFailure: false });
218+
expect(result?.success).toBeFalse();
219+
expect(logs).toContain(
220+
jasmine.objectContaining({
221+
level: 'error',
222+
message: jasmine.stringMatching(
223+
/Library bundle generation failed\. \[\d+\.\d{3} seconds\] - \d{4}-\d{2}-\d{2}T/,
224+
),
225+
}),
226+
);
227+
expect(logs).not.toContain(
228+
jasmine.objectContaining({
229+
message: jasmine.stringMatching(/Output location:/),
230+
}),
231+
);
232+
});
183233
});
184234
});

0 commit comments

Comments
 (0)