Skip to content

Commit 82b0f94

Browse files
committed
fix(@angular-devkit/build-angular): handle HMR updates of global CSS when using Vite
This commit updates the Vite based dev-server to send updates for global styles using the HMR update instead of a full page reload when the the dev-server builder `hmr` option to be enabled. (cherry picked from commit b09ce57)
1 parent 6a48a11 commit 82b0f94

File tree

1 file changed

+57
-18
lines changed
  • packages/angular_devkit/build_angular/src/builders/dev-server

1 file changed

+57
-18
lines changed

packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import type { BuilderContext } from '@angular-devkit/architect';
10-
import type { json } from '@angular-devkit/core';
10+
import type { json, logging } from '@angular-devkit/core';
1111
import type { OutputFile } from 'esbuild';
1212
import { lookup as lookupMimeType } from 'mrmime';
1313
import assert from 'node:assert';
@@ -86,23 +86,7 @@ export async function* serveWithVite(
8686
}
8787

8888
if (server) {
89-
// Invalidate any updated files
90-
for (const [file, record] of generatedFiles) {
91-
if (record.updated) {
92-
const updatedModules = server.moduleGraph.getModulesByFile(file);
93-
updatedModules?.forEach((m) => server?.moduleGraph.invalidateModule(m));
94-
}
95-
}
96-
97-
// Send reload command to clients
98-
if (serverOptions.liveReload) {
99-
context.logger.info('Reloading client(s)...');
100-
101-
server.ws.send({
102-
type: 'full-reload',
103-
path: '*',
104-
});
105-
}
89+
handleUpdate(generatedFiles, server, serverOptions, context.logger);
10690
} else {
10791
// Setup server and start listening
10892
const serverConfiguration = await setupServer(
@@ -137,6 +121,61 @@ export async function* serveWithVite(
137121
}
138122
}
139123

124+
function handleUpdate(
125+
generatedFiles: Map<string, OutputFileRecord>,
126+
server: ViteDevServer,
127+
serverOptions: NormalizedDevServerOptions,
128+
logger: logging.LoggerApi,
129+
): void {
130+
const updatedFiles: string[] = [];
131+
132+
// Invalidate any updated files
133+
for (const [file, record] of generatedFiles) {
134+
if (record.updated) {
135+
updatedFiles.push(file);
136+
const updatedModules = server.moduleGraph.getModulesByFile(file);
137+
updatedModules?.forEach((m) => server?.moduleGraph.invalidateModule(m));
138+
}
139+
}
140+
141+
if (!updatedFiles.length) {
142+
return;
143+
}
144+
145+
if (serverOptions.hmr) {
146+
if (updatedFiles.every((f) => f.endsWith('.css'))) {
147+
const timestamp = Date.now();
148+
server.ws.send({
149+
type: 'update',
150+
updates: updatedFiles.map((f) => {
151+
const filePath = f.slice(1); // Remove leading slash.
152+
153+
return {
154+
type: 'css-update',
155+
timestamp,
156+
path: filePath,
157+
acceptedPath: filePath,
158+
};
159+
}),
160+
});
161+
162+
logger.info('HMR update sent to client(s)...');
163+
164+
return;
165+
}
166+
}
167+
168+
// Send reload command to clients
169+
if (serverOptions.liveReload) {
170+
logger.info('Reloading client(s)...');
171+
172+
server.ws.send({
173+
type: 'full-reload',
174+
path: '*',
175+
});
176+
}
177+
}
178+
140179
function analyzeResultFiles(
141180
resultFiles: OutputFile[],
142181
generatedFiles: Map<string, OutputFileRecord>,

0 commit comments

Comments
 (0)