Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 096c2ce

Browse files
committed
refactor(@angular/build): separate Vite-based dev server into multiple files
To support future improvements, the Vite-based dev server core implementation is now split into several files.
1 parent e04c8aa commit 096c2ce

File tree

6 files changed

+517
-465
lines changed

6 files changed

+517
-465
lines changed

‎packages/angular/build/src/builders/dev-server/builder.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
import { normalizeOptions } from './options';
1919
import type { DevServerBuilderOutput } from './output';
2020
import type { Schema as DevServerBuilderOptions } from './schema';
21-
import { serveWithVite } from './vite-server';
21+
import { serveWithVite } from './vite';
2222

2323
/**
2424
* A Builder that executes a development server based on the provided browser target option.
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import type { ɵdestroyAngularServerApp as destroyAngularServerApp } from '@angular/ssr';
10+
import type { BuilderContext } from '@angular-devkit/architect';
11+
import { join } from 'node:path';
12+
import type { ViteDevServer } from 'vite';
13+
import type { ComponentStyleRecord } from '../../../tools/vite/middlewares';
14+
import { BuildOutputFileType } from '../internal';
15+
import type { NormalizedDevServerOptions } from '../options';
16+
import type { OutputAssetRecord, OutputFileRecord } from './utils';
17+
18+
/**
19+
* Invalidates any updated asset or generated files and resets their `updated` state.
20+
* This function also clears the server application cache when necessary.
21+
*
22+
* @returns A list of files that were updated and invalidated.
23+
*/
24+
export async function invalidateUpdatedFiles(
25+
normalizePath: (id: string) => string,
26+
generatedFiles: Map<string, OutputFileRecord>,
27+
assetFiles: Map<string, OutputAssetRecord>,
28+
server: ViteDevServer,
29+
): Promise<string[]> {
30+
const updatedFiles: string[] = [];
31+
32+
// Invalidate any updated asset
33+
for (const [file, record] of assetFiles) {
34+
if (!record.updated) {
35+
continue;
36+
}
37+
38+
record.updated = false;
39+
updatedFiles.push(file);
40+
}
41+
42+
// Invalidate any updated files
43+
let serverApplicationChanged = false;
44+
for (const [file, record] of generatedFiles) {
45+
if (!record.updated) {
46+
continue;
47+
}
48+
49+
record.updated = false;
50+
updatedFiles.push(file);
51+
serverApplicationChanged ||= record.type === BuildOutputFileType.ServerApplication;
52+
53+
const updatedModules = server.moduleGraph.getModulesByFile(
54+
normalizePath(join(server.config.root, file)),
55+
);
56+
updatedModules?.forEach((m) => server.moduleGraph.invalidateModule(m));
57+
}
58+
59+
if (serverApplicationChanged) {
60+
// Clear the server app cache and
61+
// trigger module evaluation before reload to initiate dependency optimization.
62+
const { ɵdestroyAngularServerApp } = (await server.ssrLoadModule('/main.server.mjs')) as {
63+
ɵdestroyAngularServerApp: typeof destroyAngularServerApp;
64+
};
65+
66+
ɵdestroyAngularServerApp();
67+
}
68+
69+
return updatedFiles;
70+
}
71+
72+
/**
73+
* Handles updates for the client by sending HMR or full page reload commands
74+
* based on the updated files. It also ensures proper tracking of component styles and determines if
75+
* a full reload is needed.
76+
*/
77+
export function handleUpdate(
78+
server: ViteDevServer,
79+
serverOptions: NormalizedDevServerOptions,
80+
logger: BuilderContext['logger'],
81+
componentStyles: Map<string, ComponentStyleRecord>,
82+
updatedFiles: string[],
83+
): void {
84+
if (!updatedFiles.length) {
85+
return;
86+
}
87+
88+
if (serverOptions.hmr) {
89+
if (updatedFiles.every((f) => f.endsWith('.css'))) {
90+
let requiresReload = false;
91+
const timestamp = Date.now();
92+
const updates = updatedFiles.flatMap((filePath) => {
93+
// For component styles, an HMR update must be sent for each one with the corresponding
94+
// component identifier search parameter (`ngcomp`). The Vite client code will not keep
95+
// the existing search parameters when it performs an update and each one must be
96+
// specified explicitly. Typically, there is only one each though as specific style files
97+
// are not typically reused across components.
98+
const record = componentStyles.get(filePath);
99+
if (record) {
100+
if (record.reload) {
101+
// Shadow DOM components currently require a full reload.
102+
// Vite's CSS hot replacement does not support shadow root searching.
103+
requiresReload = true;
104+
105+
return [];
106+
}
107+
108+
return Array.from(record.used ?? []).map((id) => {
109+
return {
110+
type: 'css-update' as const,
111+
timestamp,
112+
path: `${filePath}?ngcomp` + (typeof id === 'string' ? `=${id}` : ''),
113+
acceptedPath: filePath,
114+
};
115+
});
116+
}
117+
118+
return {
119+
type: 'css-update' as const,
120+
timestamp,
121+
path: filePath,
122+
acceptedPath: filePath,
123+
};
124+
});
125+
126+
if (!requiresReload) {
127+
server.ws.send({
128+
type: 'update',
129+
updates,
130+
});
131+
logger.info('Stylesheet update sent to client(s).');
132+
133+
return;
134+
}
135+
}
136+
}
137+
138+
// Send reload command to clients
139+
if (serverOptions.liveReload) {
140+
// Clear used component tracking on full reload
141+
componentStyles.forEach((record) => record.used?.clear());
142+
143+
server.ws.send({
144+
type: 'full-reload',
145+
path: '*',
146+
});
147+
148+
logger.info('Page reload sent to client(s).');
149+
}
150+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /