Skip to content

Commit 42bdb75

Browse files
MeAkibalan-agius4
authored andcommitted
fix(@angular/build): remove every output of a deleted asset in watch mode
The previous asset state was keyed by source file, so an asset copied to several destinations (two asset entries with the same input, or one copy per locale with `localize`) kept only the last destination. Deleting the source during `ng build --watch` then removed only that copy and left the others in the output directory. (cherry picked from commit ef43725)
1 parent 0f63a03 commit 42bdb75

3 files changed

Lines changed: 41 additions & 8 deletions

File tree

‎packages/angular/build/src/builders/application/build-action.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,11 @@ function* emitOutputResults(
314314
}
315315

316316
// Initially assume all previous assets files have been removed
317-
const removedAssetFiles = new Map(previousAssetsInfo);
317+
const removedAssetFiles = new Set(previousAssetsInfo);
318318
for (const { source, destination } of assetFiles) {
319-
removedAssetFiles.delete(source);
319+
removedAssetFiles.delete(destination);
320320

321-
if (!previousAssetsInfo.has(source)) {
321+
if (!previousAssetsInfo.has(destination)) {
322322
incrementalResult.added.push(destination);
323323
incrementalResult.background = false;
324324
} else if (changes.modified.has(source)) {
@@ -353,7 +353,7 @@ function* emitOutputResults(
353353
path,
354354
type,
355355
})),
356-
...Array.from(removedAssetFiles.values(), (path) => ({
356+
...Array.from(removedAssetFiles, (path) => ({
357357
path,
358358
type: BuildOutputFileType.Browser,
359359
})),

‎packages/angular/build/src/builders/application/tests/behavior/rebuild-assets_spec.ts‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,39 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
7676
},
7777
]);
7878
});
79+
80+
it('remove all outputs of a deleted asset copied to multiple destinations', async () => {
81+
harness.useTarget('build', {
82+
...BASE_OPTIONS,
83+
assets: [
84+
{
85+
glob: '**/*',
86+
input: 'public',
87+
},
88+
{
89+
glob: '**/*',
90+
input: 'public',
91+
output: 'static',
92+
},
93+
],
94+
watch: true,
95+
});
96+
97+
await harness.executeWithCases([
98+
async ({ result }) => {
99+
expect(result?.success).toBeTrue();
100+
harness.expectFile('dist/browser/asset.txt').toExist();
101+
harness.expectFile('dist/browser/static/asset.txt').toExist();
102+
103+
await harness.removeFile('public/asset.txt');
104+
},
105+
106+
({ result }) => {
107+
expect(result?.success).toBeTrue();
108+
harness.expectFile('dist/browser/asset.txt').toNotExist();
109+
harness.expectFile('dist/browser/static/asset.txt').toNotExist();
110+
},
111+
]);
112+
});
79113
});
80114
});

‎packages/angular/build/src/tools/esbuild/bundler-execution-result.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export interface RebuildState {
3131
string,
3232
{ hash: string; type: BuildOutputFileType; path: string }
3333
>;
34-
previousAssetsInfo: ReadonlyMap<string, string>;
34+
previousAssetsInfo: ReadonlySet<string>;
3535
templateUpdates?: Map<string, string>;
3636
}
3737

@@ -176,9 +176,8 @@ export class ExecutionResult {
176176
previousOutputInfo: new Map(
177177
this.outputFiles.map(({ path, hash, type }) => [`${type}:${path}`, { hash, type, path }]),
178178
),
179-
previousAssetsInfo: new Map(
180-
this.assetFiles.map(({ source, destination }) => [source, destination]),
181-
),
179+
// Tracked by destination since one source can be copied to several outputs (e.g. per locale).
180+
previousAssetsInfo: new Set(this.assetFiles.map(({ destination }) => destination)),
182181
templateUpdates: this.templateUpdates,
183182
};
184183
}

0 commit comments

Comments
 (0)