Skip to content

Commit 7d8c341

Browse files
clydinalan-agius4
authored andcommittedJan 20, 2025·
fix(@angular/build): allow asset changes to reload page on incremental updates
Changes to asset files were previously not considered when determining if an incremental build result could be background update and not cause a page reload. Asset modifications will not cause a page reload in incremental update cases. Additionally, a superfluous component update result will no longer be emitted in this case. The required page reload will account for the component updates. (cherry picked from commit 102d92b)
1 parent 4a9fb58 commit 7d8c341

File tree

1 file changed

+105
-99
lines changed

1 file changed

+105
-99
lines changed
 

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

+105-99
Original file line numberDiff line numberDiff line change
@@ -242,33 +242,11 @@ function* emitOutputResults(
242242
return;
243243
}
244244

245-
// Template updates only exist if no other JS changes have occurred
246-
const hasTemplateUpdates = !!templateUpdates?.size;
247-
if (hasTemplateUpdates) {
248-
const updateResult: ComponentUpdateResult = {
249-
kind: ResultKind.ComponentUpdate,
250-
updates: Array.from(templateUpdates, ([id, content]) => ({
251-
type: 'template',
252-
id,
253-
content,
254-
})),
255-
};
256-
257-
yield updateResult;
258-
}
259-
260-
// Use an incremental result if previous output information is available
261-
if (rebuildState && changes) {
262-
const { previousAssetsInfo, previousOutputInfo } = rebuildState;
263-
264-
const incrementalResult: IncrementalResult = {
265-
kind: ResultKind.Incremental,
245+
// Use a full result if there is no rebuild state (no prior build result)
246+
if (!rebuildState || !changes) {
247+
const result: FullResult = {
248+
kind: ResultKind.Full,
266249
warnings: warnings as ResultMessage[],
267-
// These files need to be updated in the dev server but should not signal any updates
268-
background: hasTemplateUpdates,
269-
added: [],
270-
removed: [],
271-
modified: [],
272250
files: {},
273251
detail: {
274252
externalMetadata,
@@ -277,78 +255,42 @@ function* emitOutputResults(
277255
outputOptions,
278256
},
279257
};
280-
281-
// Initially assume all previous output files have been removed
282-
const removedOutputFiles = new Map(previousOutputInfo);
283-
for (const file of outputFiles) {
284-
removedOutputFiles.delete(file.path);
285-
286-
const previousHash = previousOutputInfo.get(file.path)?.hash;
287-
let needFile = false;
288-
if (previousHash === undefined) {
289-
needFile = true;
290-
incrementalResult.added.push(file.path);
291-
} else if (previousHash !== file.hash) {
292-
needFile = true;
293-
incrementalResult.modified.push(file.path);
294-
}
295-
296-
if (needFile) {
297-
// Updates to non-JS files must signal an update with the dev server
298-
if (!/(?:\.m?js|\.map)?$/.test(file.path)) {
299-
incrementalResult.background = false;
300-
}
301-
302-
incrementalResult.files[file.path] = {
303-
type: file.type,
304-
contents: file.contents,
305-
origin: 'memory',
306-
hash: file.hash,
307-
};
308-
}
309-
}
310-
311-
// Initially assume all previous assets files have been removed
312-
const removedAssetFiles = new Map(previousAssetsInfo);
313-
for (const { source, destination } of assetFiles) {
314-
removedAssetFiles.delete(source);
315-
316-
if (!previousAssetsInfo.has(source)) {
317-
incrementalResult.added.push(destination);
318-
} else if (changes.modified.has(source)) {
319-
incrementalResult.modified.push(destination);
320-
} else {
321-
continue;
322-
}
323-
324-
incrementalResult.files[destination] = {
258+
for (const file of assetFiles) {
259+
result.files[file.destination] = {
325260
type: BuildOutputFileType.Browser,
326-
inputPath: source,
261+
inputPath: file.source,
327262
origin: 'disk',
328263
};
329264
}
265+
for (const file of outputFiles) {
266+
result.files[file.path] = {
267+
type: file.type,
268+
contents: file.contents,
269+
origin: 'memory',
270+
hash: file.hash,
271+
};
272+
}
330273

331-
// Include the removed output and asset files
332-
incrementalResult.removed.push(
333-
...Array.from(removedOutputFiles, ([file, { type }]) => ({
334-
path: file,
335-
type,
336-
})),
337-
...Array.from(removedAssetFiles.values(), (file) => ({
338-
path: file,
339-
type: BuildOutputFileType.Browser,
340-
})),
341-
);
342-
343-
yield incrementalResult;
274+
yield result;
344275

345276
return;
346277
}
347278

348-
// Otherwise, use a full result
349-
const result: FullResult = {
350-
kind: ResultKind.Full,
279+
// Template updates only exist if no other JS changes have occurred.
280+
// A full page reload may be required based on the following incremental output change analysis.
281+
const hasTemplateUpdates = !!templateUpdates?.size;
282+
283+
// Use an incremental result if previous output information is available
284+
const { previousAssetsInfo, previousOutputInfo } = rebuildState;
285+
286+
const incrementalResult: IncrementalResult = {
287+
kind: ResultKind.Incremental,
351288
warnings: warnings as ResultMessage[],
289+
// Initially attempt to use a background update of files to support component updates.
290+
background: hasTemplateUpdates,
291+
added: [],
292+
removed: [],
293+
modified: [],
352294
files: {},
353295
detail: {
354296
externalMetadata,
@@ -357,21 +299,85 @@ function* emitOutputResults(
357299
outputOptions,
358300
},
359301
};
360-
for (const file of assetFiles) {
361-
result.files[file.destination] = {
302+
303+
// Initially assume all previous output files have been removed
304+
const removedOutputFiles = new Map(previousOutputInfo);
305+
for (const file of outputFiles) {
306+
removedOutputFiles.delete(file.path);
307+
308+
const previousHash = previousOutputInfo.get(file.path)?.hash;
309+
let needFile = false;
310+
if (previousHash === undefined) {
311+
needFile = true;
312+
incrementalResult.added.push(file.path);
313+
} else if (previousHash !== file.hash) {
314+
needFile = true;
315+
incrementalResult.modified.push(file.path);
316+
}
317+
318+
if (needFile) {
319+
// Updates to non-JS files must signal an update with the dev server
320+
if (!/(?:\.m?js|\.map)$/.test(file.path)) {
321+
incrementalResult.background = false;
322+
}
323+
324+
incrementalResult.files[file.path] = {
325+
type: file.type,
326+
contents: file.contents,
327+
origin: 'memory',
328+
hash: file.hash,
329+
};
330+
}
331+
}
332+
333+
// Initially assume all previous assets files have been removed
334+
const removedAssetFiles = new Map(previousAssetsInfo);
335+
for (const { source, destination } of assetFiles) {
336+
removedAssetFiles.delete(source);
337+
338+
if (!previousAssetsInfo.has(source)) {
339+
incrementalResult.added.push(destination);
340+
incrementalResult.background = false;
341+
} else if (changes.modified.has(source)) {
342+
incrementalResult.modified.push(destination);
343+
incrementalResult.background = false;
344+
} else {
345+
continue;
346+
}
347+
348+
incrementalResult.files[destination] = {
362349
type: BuildOutputFileType.Browser,
363-
inputPath: file.source,
350+
inputPath: source,
364351
origin: 'disk',
365352
};
366353
}
367-
for (const file of outputFiles) {
368-
result.files[file.path] = {
369-
type: file.type,
370-
contents: file.contents,
371-
origin: 'memory',
372-
hash: file.hash,
354+
355+
// Include the removed output and asset files
356+
incrementalResult.removed.push(
357+
...Array.from(removedOutputFiles, ([file, { type }]) => ({
358+
path: file,
359+
type,
360+
})),
361+
...Array.from(removedAssetFiles.values(), (file) => ({
362+
path: file,
363+
type: BuildOutputFileType.Browser,
364+
})),
365+
);
366+
367+
yield incrementalResult;
368+
369+
// If there are template updates and the incremental update was background only, a component
370+
// update is possible.
371+
if (hasTemplateUpdates && incrementalResult.background) {
372+
const updateResult: ComponentUpdateResult = {
373+
kind: ResultKind.ComponentUpdate,
374+
updates: Array.from(templateUpdates, ([id, content]) => ({
375+
type: 'template',
376+
id,
377+
content,
378+
})),
373379
};
374-
}
375380

376-
yield result;
381+
yield updateResult;
382+
}
377383
}

0 commit comments

Comments
 (0)
Please sign in to comment.