Skip to content

Commit e02ceba

Browse files
committed
fixup! refactor(@angular/build): consolidate library asset collection and watch check
1 parent 5f90459 commit e02ceba

4 files changed

Lines changed: 78 additions & 45 deletions

File tree

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

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,14 @@ export async function* executeLibraryBuilder(
107107
target,
108108
);
109109

110-
// Track all referenced files for watch mode
111-
const allWatchedFiles = new Set<string>([
110+
// Track all referenced compilation files for watch mode
111+
const watchedCompilationFiles = new Set<string>([
112112
toPosixPath(tsConfigPath),
113113
toPosixPath(packageJsonPath),
114114
]);
115115

116116
for (const entryPoint of normalizedOptions.entryPoints.values()) {
117-
allWatchedFiles.add(toPosixPath(entryPoint.entryFilePath));
117+
watchedCompilationFiles.add(toPosixPath(entryPoint.entryFilePath));
118118
}
119119

120120
if (isWatchMode) {
@@ -131,7 +131,7 @@ export async function* executeLibraryBuilder(
131131
poll,
132132
preserveSymlinks,
133133
signal,
134-
watchFiles: allWatchedFiles,
134+
watchFiles: watchedCompilationFiles,
135135
});
136136

137137
context.addTeardown?.(() => void watcher?.close());
@@ -143,7 +143,7 @@ export async function* executeLibraryBuilder(
143143
{
144144
options: normalizedOptions,
145145
stylesheetBundler,
146-
allWatchedFiles,
146+
watchedCompilationFiles,
147147
isWatchMode,
148148
context,
149149
buildState,
@@ -162,7 +162,7 @@ export async function* executeLibraryBuilder(
162162
watcher,
163163
normalizedOptions,
164164
stylesheetBundler,
165-
allWatchedFiles,
165+
watchedCompilationFiles,
166166
context,
167167
withProgress,
168168
buildState,
@@ -190,7 +190,7 @@ async function executeBuild(
190190
buildAction: typeof import('./pipeline/build-action').buildAction,
191191
): Promise<BuilderOutput> {
192192
const startTime = process.hrtime.bigint();
193-
const { context, allWatchedFiles, isWatchMode } = actionContext;
193+
const { context, watchedCompilationFiles, isWatchMode } = actionContext;
194194

195195
try {
196196
await withProgress(message, () => buildAction(actionContext));
@@ -206,7 +206,14 @@ async function executeBuild(
206206

207207
return { success: false, error: error.message };
208208
} finally {
209-
watcher?.add(Array.from(allWatchedFiles));
209+
if (watcher) {
210+
watcher.add(Array.from(watchedCompilationFiles));
211+
212+
const { assetsToEmit } = actionContext;
213+
if (assetsToEmit?.length) {
214+
watcher.add(assetsToEmit.map((asset) => asset.source));
215+
}
216+
}
210217
}
211218
}
212219

@@ -217,7 +224,7 @@ async function* runWatchLoop(
217224
watcher: BuildWatcher,
218225
options: NormalizedLibraryOptions,
219226
stylesheetBundler: ReturnType<typeof createComponentStylesheetBundlerForLibrary>,
220-
allWatchedFiles: Set<string>,
227+
watchedCompilationFiles: Set<string>,
221228
context: BuilderContext,
222229
withProgress: typeof withSpinner,
223230
buildState: SingleBuildState,
@@ -281,7 +288,7 @@ async function* runWatchLoop(
281288
packageJson,
282289
options,
283290
buildState,
284-
allWatchedFiles,
291+
watchedCompilationFiles,
285292
packageJsonPath,
286293
);
287294

@@ -302,7 +309,7 @@ async function* runWatchLoop(
302309
!buildState.singleProgramCache ||
303310
buildState.hasCompilationError ||
304311
buildState.hasEntryPointsChanges ||
305-
hasModifiedWatchedFile(changedFiles, allWatchedFiles, posixPackageJsonPath);
312+
hasModifiedWatchedFile(changedFiles, watchedCompilationFiles, posixPackageJsonPath);
306313

307314
const assetsToEmit = await collectAssetsToEmit(
308315
assets,
@@ -319,7 +326,7 @@ async function* runWatchLoop(
319326
{
320327
options,
321328
stylesheetBundler,
322-
allWatchedFiles,
329+
watchedCompilationFiles,
323330
isWatchMode: true,
324331
context,
325332
buildState,

‎packages/angular/build/src/builders/library/pipeline/build-action.ts‎

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
import type { BuilderContext } from '@angular-devkit/architect';
1010
import { constants, copyFile, mkdir, writeFile } from 'node:fs/promises';
1111
import path from 'node:path';
12+
import type { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/component-stylesheets';
1213
import { emitFilesToDisk } from '../../../tools/esbuild/utils';
1314
import { toPosixPath } from '../../../utils/path';
1415
import type { NormalizedLibraryOptions, SingleBuildState } from '../types';
1516
import { collectAssetsToEmit } from './assets';
1617
import { type BundleEntryPointInput, bundleEntryPoints } from './bundler';
1718
import { compileLibrary } from './compilation';
1819
import { generatePackageManifests } from './package-manifests';
19-
import type { createComponentStylesheetBundlerForLibrary } from './stylesheet-bundler';
2020
import type { DiskOutputFile, OutputFile } from './utils';
2121

2222
/**
@@ -35,13 +35,39 @@ export function createSingleBuildState(): SingleBuildState {
3535
* Context required to execute a single library build iteration.
3636
*/
3737
export interface BuildActionContext {
38+
/** Normalized options for the library build. */
3839
options: NormalizedLibraryOptions;
40+
41+
/** The Architect builder context. */
3942
context: BuilderContext;
40-
stylesheetBundler: ReturnType<typeof createComponentStylesheetBundlerForLibrary>;
43+
44+
/** Bundler instance used to process component stylesheets. */
45+
stylesheetBundler: ComponentStylesheetBundler;
46+
47+
/** Whether the builder is running in watch mode. */
4148
isWatchMode: boolean;
42-
allWatchedFiles: Set<string>;
49+
50+
/**
51+
* Set of file paths tracked for compilation and configuration
52+
* (including `tsconfig.json`, `package.json`, entry points, and referenced source,
53+
* template, and stylesheet files). Updated during compilation and used to determine
54+
* whether file changes require recompiling entry points, excluding asset files so
55+
* asset-only changes do not trigger code compilation.
56+
*/
57+
watchedCompilationFiles: Set<string>;
58+
59+
/** State preserved across incremental builds in watch mode. */
4360
buildState: SingleBuildState;
61+
62+
/** Set of file paths modified since the last build iteration. */
4463
modifiedFiles?: Set<string>;
64+
65+
/**
66+
* Asset files to emit to disk for the current build iteration.
67+
* Pre-collected in the watch loop to avoid redundant asset matching, or resolved and
68+
* populated by `buildAction` when omitted (such as during the initial build) so the
69+
* caller can register their source paths with the file watcher.
70+
*/
4571
assetsToEmit?: DiskOutputFile[];
4672
}
4773

@@ -58,10 +84,9 @@ export async function buildAction(actionContext: BuildActionContext): Promise<vo
5884
context,
5985
stylesheetBundler,
6086
isWatchMode,
61-
allWatchedFiles,
87+
watchedCompilationFiles,
6288
buildState,
6389
modifiedFiles,
64-
assetsToEmit,
6590
} = actionContext;
6691

6792
const posixPackageJsonPath = toPosixPath(options.packageJsonPath);
@@ -78,7 +103,7 @@ export async function buildAction(actionContext: BuildActionContext): Promise<vo
78103
buildState.hasEntryPointsChanges ||
79104
pendingChangedEsmFiles.size > 0 ||
80105
pendingChangedDtsFiles.size > 0 ||
81-
hasModifiedWatchedFile(modifiedFiles, allWatchedFiles, posixPackageJsonPath);
106+
hasModifiedWatchedFile(modifiedFiles, watchedCompilationFiles, posixPackageJsonPath);
82107
const shouldGenerateManifests = !buildState.hasEmittedManifests;
83108

84109
if (shouldGenerateManifests) {
@@ -109,7 +134,7 @@ export async function buildAction(actionContext: BuildActionContext): Promise<vo
109134
buildState.singleProgramCache = cache;
110135

111136
for (const file of referencedFiles) {
112-
allWatchedFiles.add(file);
137+
watchedCompilationFiles.add(file);
113138
}
114139

115140
for (const file of changedEsmFiles) {
@@ -172,16 +197,11 @@ export async function buildAction(actionContext: BuildActionContext): Promise<vo
172197
filesToEmit.push(...generatePackageManifests(options, isWatchMode));
173198
}
174199

175-
const resolvedAssetsToEmit =
176-
assetsToEmit ??
177-
(await collectAssetsToEmit(
178-
options.assets,
179-
options.workspaceRoot,
180-
buildState.hasEmittedAssets ? modifiedFiles : undefined,
181-
));
182-
for (const asset of resolvedAssetsToEmit) {
183-
allWatchedFiles.add(toPosixPath(asset.source));
184-
}
200+
const resolvedAssetsToEmit = (actionContext.assetsToEmit ??= await collectAssetsToEmit(
201+
options.assets,
202+
options.workspaceRoot,
203+
buildState.hasEmittedAssets ? modifiedFiles : undefined,
204+
));
185205
filesToEmit.push(...resolvedAssetsToEmit);
186206

187207
await emitFilesToDisk<OutputFile>(filesToEmit, async (file) => {
@@ -205,11 +225,11 @@ export async function buildAction(actionContext: BuildActionContext): Promise<vo
205225

206226
export function hasModifiedWatchedFile(
207227
modifiedFiles: ReadonlySet<string>,
208-
allWatchedFiles: ReadonlySet<string>,
228+
watchedCompilationFiles: ReadonlySet<string>,
209229
posixPackageJsonPath: string,
210230
): boolean {
211231
for (const file of modifiedFiles) {
212-
if (file !== posixPackageJsonPath && allWatchedFiles.has(file)) {
232+
if (file !== posixPackageJsonPath && watchedCompilationFiles.has(file)) {
213233
return true;
214234
}
215235
}

‎packages/angular/build/src/builders/library/pipeline/entry-points.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ export function updateWatchedEntryPoints(
238238
packageJson: PackageJsonData,
239239
options: NormalizedLibraryOptions,
240240
buildState: SingleBuildState,
241-
allWatchedFiles: Set<string>,
241+
watchedCompilationFiles: Set<string>,
242242
packageJsonPath: string,
243243
): void {
244244
const newEntryPoints = normalizeEntryPoints(
@@ -250,7 +250,7 @@ export function updateWatchedEntryPoints(
250250

251251
if (haveEntryPointsChanged(options.entryPoints, newEntryPoints)) {
252252
for (const entryPoint of newEntryPoints.values()) {
253-
allWatchedFiles.add(toPosixPath(entryPoint.entryFilePath));
253+
watchedCompilationFiles.add(toPosixPath(entryPoint.entryFilePath));
254254
}
255255

256256
for (const name of buildState.previousBundleResults.keys()) {

‎packages/angular/build/src/builders/library/pipeline/entry-points_spec.ts‎

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ describe('entry-points pipeline', () => {
530530
hasEntryPointsChanges: false,
531531
} as unknown as SingleBuildState;
532532

533-
const allWatchedFiles = new Set<string>();
533+
const watchedCompilationFiles = new Set<string>();
534534

535535
const newPackageJson: PackageJsonData = {
536536
name: packageName,
@@ -544,7 +544,7 @@ describe('entry-points pipeline', () => {
544544
newPackageJson,
545545
options,
546546
buildState,
547-
allWatchedFiles,
547+
watchedCompilationFiles,
548548
packageJsonPath,
549549
);
550550

@@ -553,9 +553,13 @@ describe('entry-points pipeline', () => {
553553
expect(options.entryPoints.has('old-feature')).toBeFalse();
554554
expect(buildState.previousBundleResults.has('old-feature')).toBeFalse();
555555
expect(buildState.previousBundleResults.has('.')).toBeTrue();
556-
expect(allWatchedFiles.has(toPosixPath(join(projectRoot, 'src/public-api.ts')))).toBeTrue();
557556
expect(
558-
allWatchedFiles.has(toPosixPath(join(projectRoot, 'new-feature/src/public-api.ts'))),
557+
watchedCompilationFiles.has(toPosixPath(join(projectRoot, 'src/public-api.ts'))),
558+
).toBeTrue();
559+
expect(
560+
watchedCompilationFiles.has(
561+
toPosixPath(join(projectRoot, 'new-feature/src/public-api.ts')),
562+
),
559563
).toBeTrue();
560564
});
561565

@@ -584,7 +588,7 @@ describe('entry-points pipeline', () => {
584588
hasEntryPointsChanges: false,
585589
} as unknown as SingleBuildState;
586590

587-
const allWatchedFiles = new Set<string>();
591+
const watchedCompilationFiles = new Set<string>();
588592

589593
const samePackageJson: PackageJsonData = {
590594
name: packageName,
@@ -598,13 +602,13 @@ describe('entry-points pipeline', () => {
598602
samePackageJson,
599603
options,
600604
buildState,
601-
allWatchedFiles,
605+
watchedCompilationFiles,
602606
packageJsonPath,
603607
);
604608

605609
expect(buildState.hasEntryPointsChanges).toBeFalse();
606610
expect(options.entryPoints).toBe(initialEntryPoints);
607-
expect(allWatchedFiles).toHaveSize(0);
611+
expect(watchedCompilationFiles).toHaveSize(0);
608612
expect(buildState.previousBundleResults).toHaveSize(2);
609613
});
610614

@@ -631,7 +635,7 @@ describe('entry-points pipeline', () => {
631635
hasEntryPointsChanges: false,
632636
} as unknown as SingleBuildState;
633637

634-
const allWatchedFiles = new Set<string>();
638+
const watchedCompilationFiles = new Set<string>();
635639

636640
const updatedPackageJson: PackageJsonData = {
637641
name: packageName,
@@ -644,7 +648,7 @@ describe('entry-points pipeline', () => {
644648
updatedPackageJson,
645649
options,
646650
buildState,
647-
allWatchedFiles,
651+
watchedCompilationFiles,
648652
packageJsonPath,
649653
);
650654

@@ -653,7 +657,9 @@ describe('entry-points pipeline', () => {
653657
expect(options.entryPoints.get('.')?.entryFilePath).toBe(
654658
join(projectRoot, 'src/other-api.ts'),
655659
);
656-
expect(allWatchedFiles.has(toPosixPath(join(projectRoot, 'src/other-api.ts')))).toBeTrue();
660+
expect(
661+
watchedCompilationFiles.has(toPosixPath(join(projectRoot, 'src/other-api.ts'))),
662+
).toBeTrue();
657663
});
658664

659665
it('should prune previousBundleResults when an entry point bundleName changes', () => {
@@ -679,7 +685,7 @@ describe('entry-points pipeline', () => {
679685
hasEntryPointsChanges: false,
680686
} as unknown as SingleBuildState;
681687

682-
const allWatchedFiles = new Set<string>();
688+
const watchedCompilationFiles = new Set<string>();
683689

684690
const updatedPackageJson: PackageJsonData = {
685691
name: '@renamed-scope/my-lib',
@@ -694,7 +700,7 @@ describe('entry-points pipeline', () => {
694700
updatedPackageJson,
695701
options,
696702
buildState,
697-
allWatchedFiles,
703+
watchedCompilationFiles,
698704
packageJsonPath,
699705
);
700706

0 commit comments

Comments
 (0)