Skip to content

Commit 3b7e6a8

Browse files
clydindgp1130
authored andcommitted
fix(@angular/build): invalidate component template updates with dev-server SSR
To ensure that the Vite-based dev-server SSR uses updated component template update modules, the server module graph is invalidated when component updates are sent. This currently does a full invalidation but in the future this could potentially be optimized to only update the relevant modules. A fix is also present to correct the component update identifier usage to prevent lookup misses.
1 parent 19bb2d4 commit 3b7e6a8

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

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

+16
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ export async function* serveWithVite(
233233
assetFiles.set('/' + normalizePath(outputPath), normalizePath(file.inputPath));
234234
}
235235
}
236+
237+
// Invalidate SSR module graph to ensure that only new rebuild is used and not stale component updates
238+
if (server && browserOptions.ssr && templateUpdates.size > 0) {
239+
server.moduleGraph.invalidateAll();
240+
}
241+
236242
// Clear stale template updates on code rebuilds
237243
templateUpdates.clear();
238244

@@ -256,6 +262,16 @@ export async function* serveWithVite(
256262
'Builder must provide an initial full build before component update results.',
257263
);
258264

265+
// Invalidate SSR module graph to ensure that new component updates are used
266+
// TODO: Use fine-grained invalidation of only the component update modules
267+
if (browserOptions.ssr) {
268+
server.moduleGraph.invalidateAll();
269+
const { ɵresetCompiledComponents } = (await server.ssrLoadModule('/main.server.mjs')) as {
270+
ɵresetCompiledComponents: () => void;
271+
};
272+
ɵresetCompiledComponents();
273+
}
274+
259275
for (const componentUpdate of result.updates) {
260276
if (componentUpdate.type === 'template') {
261277
templateUpdates.set(componentUpdate.id, componentUpdate.content);

Diff for: packages/angular/build/src/tools/esbuild/application-code-bundle.ts

+3
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ export function createServerMainCodeBundleOptions(
357357
ɵgetOrCreateAngularServerApp,
358358
} from '@angular/ssr';`,
359359

360+
// Need for HMR
361+
`export { ɵresetCompiledComponents } from '@angular/core';`,
362+
360363
// Re-export all symbols including default export from 'main.server.ts'
361364
`export { default } from '${mainServerEntryPointJsImport}';`,
362365
`export * from '${mainServerEntryPointJsImport}';`,

Diff for: packages/angular/build/src/tools/vite/plugins/angular-memory-plugin.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export async function createAngularMemoryPlugin(
7878
const requestUrl = new URL(id.slice(1), 'http://localhost');
7979
const componentId = requestUrl.searchParams.get('c');
8080

81-
return (componentId && options.templateUpdates?.get(componentId)) ?? '';
81+
return (componentId && options.templateUpdates?.get(encodeURIComponent(componentId))) ?? '';
8282
}
8383

8484
const [file] = id.split('?', 1);

0 commit comments

Comments
 (0)