diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index d3c1adcd4547..f8f3c0c96639 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -300,6 +300,8 @@ function* emitOutputResults( }, }; + let hasCssUpdates = false; + // Initially assume all previous output files have been removed const removedOutputFiles = new Map(previousOutputInfo); for (const file of outputFiles) { @@ -316,8 +318,10 @@ function* emitOutputResults( } if (needFile) { - // Updates to non-JS files must signal an update with the dev server - if (!/(?:\.m?js|\.map)$/.test(file.path)) { + if (file.path.endsWith('.css')) { + hasCssUpdates = true; + } else if (!/(?:\.m?js|\.map)$/.test(file.path)) { + // Updates to non-JS files must signal an update with the dev server incrementalResult.background = false; } @@ -345,6 +349,8 @@ function* emitOutputResults( continue; } + hasCssUpdates ||= destination.endsWith('.css'); + incrementalResult.files[destination] = { type: BuildOutputFileType.Browser, inputPath: source, @@ -369,6 +375,21 @@ function* emitOutputResults( // If there are template updates and the incremental update was background only, a component // update is possible. if (hasTemplateUpdates && incrementalResult.background) { + // Template changes may be accompanied by stylesheet changes and these should also be updated hot when possible. + if (hasCssUpdates) { + const styleResult: IncrementalResult = { + kind: ResultKind.Incremental, + added: incrementalResult.added.filter(isCssFilePath), + removed: incrementalResult.removed.filter(({ path }) => isCssFilePath(path)), + modified: incrementalResult.modified.filter(isCssFilePath), + files: Object.fromEntries( + Object.entries(incrementalResult.files).filter(([path]) => isCssFilePath(path)), + ), + }; + + yield styleResult; + } + const updateResult: ComponentUpdateResult = { kind: ResultKind.ComponentUpdate, updates: Array.from(templateUpdates, ([id, content]) => ({ @@ -381,3 +402,7 @@ function* emitOutputResults( yield updateResult; } } + +function isCssFilePath(filePath: string): boolean { + return /\.css(?:\.map)?$/i.test(filePath); +} diff --git a/packages/angular/build/src/builders/dev-server/vite-server.ts b/packages/angular/build/src/builders/dev-server/vite-server.ts index c27423985aeb..f235b5f6f8a9 100644 --- a/packages/angular/build/src/builders/dev-server/vite-server.ts +++ b/packages/angular/build/src/builders/dev-server/vite-server.ts @@ -589,7 +589,7 @@ function handleUpdate( type: 'update', updates, }); - logger.info('HMR update sent to client(s).'); + logger.info('Stylesheet update sent to client(s).'); return; }