Skip to content

Commit 376ee99

Browse files
committedDec 11, 2024·
fix(@angular/build): provide component HMR update modules to dev-server SSR
When using component HMR and SSR with the development server, the component update modules will now be available to the Vite server rendering. This prevents console errors due to missing component update paths. Additionally, it allows the server rendering to use the latest component templates if those have been changed before a new rebuild has occurred. (cherry picked from commit 64f32c7)
1 parent 4203efb commit 376ee99

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed
 

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

+1
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ export async function setupServer(
751751
await createAngularMemoryPlugin({
752752
virtualProjectRoot,
753753
outputFiles,
754+
templateUpdates,
754755
external: externalMetadata.explicitBrowser,
755756
skipViteClient: serverOptions.liveReload === false && serverOptions.hmr === false,
756757
}),

‎packages/angular/build/src/tools/vite/plugins/angular-memory-plugin.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@ import { AngularMemoryOutputFiles } from '../utils';
1616
interface AngularMemoryPluginOptions {
1717
virtualProjectRoot: string;
1818
outputFiles: AngularMemoryOutputFiles;
19+
templateUpdates?: ReadonlyMap<string, string>;
1920
external?: string[];
2021
skipViteClient?: boolean;
2122
}
2223

24+
const ANGULAR_PREFIX = '/@ng/';
25+
2326
export async function createAngularMemoryPlugin(
2427
options: AngularMemoryPluginOptions,
2528
): Promise<Plugin> {
@@ -30,7 +33,12 @@ export async function createAngularMemoryPlugin(
3033
name: 'vite:angular-memory',
3134
// Ensures plugin hooks run before built-in Vite hooks
3235
enforce: 'pre',
33-
async resolveId(source, importer) {
36+
async resolveId(source, importer, { ssr }) {
37+
// For SSR with component HMR, pass through as a virtual module
38+
if (ssr && source.startsWith(ANGULAR_PREFIX)) {
39+
return '\0' + source;
40+
}
41+
3442
// Prevent vite from resolving an explicit external dependency (`externalDependencies` option)
3543
if (external?.includes(source)) {
3644
// This is still not ideal since Vite will still transform the import specifier to
@@ -51,7 +59,16 @@ export async function createAngularMemoryPlugin(
5159
return join(virtualProjectRoot, source);
5260
}
5361
},
54-
load(id) {
62+
load(id, loadOptions) {
63+
// For SSR component updates, return the component update module or empty if none
64+
if (loadOptions?.ssr && id.startsWith(`\0${ANGULAR_PREFIX}`)) {
65+
// Extract component identifier (first character is rollup virtual module null)
66+
const requestUrl = new URL(id.slice(1), 'http://localhost');
67+
const componentId = requestUrl.searchParams.get('c');
68+
69+
return (componentId && options.templateUpdates?.get(componentId)) ?? '';
70+
}
71+
5572
const [file] = id.split('?', 1);
5673
const relativeFile = '/' + normalizePath(relative(virtualProjectRoot, file));
5774
const codeContents = outputFiles.get(relativeFile)?.contents;

0 commit comments

Comments
 (0)
Please sign in to comment.