Skip to content

Commit bf51992

Browse files
committed
fix(@angular/build): fix tailwind css update on template hmr change
When adding tailwind classes to a template, the builder notifies vite with a ComponentUpdate which reloads the template on the client with the new classes. However, if the global styles.css from the build output was changed due to a new class being added there. The client won't be served that new styles.css- until a Full Update or rebuild occurs. This commit is primarily a workaround until better support can be added for this scenario.
1 parent 64f32c7 commit bf51992

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,25 @@ async function emitOutputResult(
223223
}
224224

225225
// Template updates only exist if no other changes have occurred
226+
// To support Tailwind CSS the global styles.css build output is included in the update so it can be checked for changes
227+
// as the file watcher is only capable of detecting changes to the raw styles.css file.
226228
if (templateUpdates?.size) {
229+
const globalStyles = outputFiles.find((f) => f.path === 'styles.css');
227230
const updateResult: ComponentUpdateResult = {
228231
kind: ResultKind.ComponentUpdate,
229232
updates: Array.from(templateUpdates).map(([id, content]) => ({
230233
type: 'template',
231234
id,
232235
content,
233236
})),
237+
globalStyles: globalStyles
238+
? {
239+
origin: 'memory',
240+
hash: globalStyles.hash,
241+
type: globalStyles.type,
242+
contents: globalStyles.contents,
243+
}
244+
: undefined,
234245
};
235246

236247
return updateResult;

packages/angular/build/src/builders/application/results.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,5 @@ export interface ComponentUpdateResult extends BaseResult {
7373
type: 'style' | 'template';
7474
content: string;
7575
}[];
76+
globalStyles?: MemoryFile;
7677
}

packages/angular/build/src/builders/dev-server/vite-server.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { EsbuildLoaderOption, getDepOptimizationConfig } from '../../tools/vite/
2727
import { loadProxyConfiguration, normalizeSourceMaps } from '../../utils';
2828
import { useComponentStyleHmr, useComponentTemplateHmr } from '../../utils/environment-options';
2929
import { loadEsmModule } from '../../utils/load-esm';
30-
import { Result, ResultFile, ResultKind } from '../application/results';
30+
import { MemoryFile, Result, ResultFile, ResultKind } from '../application/results';
3131
import {
3232
type ApplicationBuilderInternalOptions,
3333
BuildOutputFileType,
@@ -265,6 +265,11 @@ export async function* serveWithVite(
265265
});
266266
}
267267
}
268+
269+
if (result.globalStyles) {
270+
updateGlobalStyles(result.globalStyles, generatedFiles, server);
271+
}
272+
268273
context.logger.info('Component update sent to client(s).');
269274
continue;
270275
default:
@@ -611,6 +616,37 @@ function analyzeResultFiles(
611616
}
612617
}
613618

619+
function updateGlobalStyles(
620+
file: MemoryFile,
621+
generatedFiles: Map<string, OutputFileRecord>,
622+
server: ViteDevServer,
623+
) {
624+
const stylesUrl = '/styles.css';
625+
const styleHash = generatedFiles.get(stylesUrl);
626+
if (file.hash !== styleHash?.hash) {
627+
generatedFiles.set(stylesUrl, {
628+
contents: file.contents,
629+
size: file.contents.byteLength,
630+
hash: file.hash,
631+
updated: true,
632+
type: file.type,
633+
servable: true,
634+
});
635+
const timestamp = Date.now();
636+
server.ws.send({
637+
type: 'update',
638+
updates: [
639+
{
640+
type: 'css-update' as const,
641+
timestamp,
642+
path: stylesUrl,
643+
acceptedPath: stylesUrl,
644+
},
645+
],
646+
});
647+
}
648+
}
649+
614650
export async function setupServer(
615651
serverOptions: NormalizedDevServerOptions,
616652
outputFiles: Map<string, OutputFileRecord>,

0 commit comments

Comments
 (0)