mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-18 03:23:57 +08:00
fix(@angular/ssr): show error when multiple routes are set with RenderMode.AppShell
This change introduces error handling to ensure that when multiple routes are configured with `RenderMode.AppShell`, an error message is displayed. This prevents misconfiguration and enhances clarity in route management.
This commit is contained in:
parent
50df631960
commit
64c52521d0
@ -45,7 +45,7 @@ const VALID_REDIRECT_RESPONSE_CODES = new Set([301, 302, 303, 307, 308]);
|
|||||||
*/
|
*/
|
||||||
type ServerConfigRouteTreeAdditionalMetadata = Partial<ServerRoute> & {
|
type ServerConfigRouteTreeAdditionalMetadata = Partial<ServerRoute> & {
|
||||||
/** Indicates if the route has been matched with the Angular router routes. */
|
/** Indicates if the route has been matched with the Angular router routes. */
|
||||||
matched?: boolean;
|
presentInClientRouter?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,7 +134,7 @@ async function* traverseRoutesConfig(options: {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
matchedMetaData.matched = true;
|
matchedMetaData.presentInClientRouter = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const metadata: ServerConfigRouteTreeNodeMetadata = {
|
const metadata: ServerConfigRouteTreeNodeMetadata = {
|
||||||
@ -142,7 +142,7 @@ async function* traverseRoutesConfig(options: {
|
|||||||
route: currentRoutePath,
|
route: currentRoutePath,
|
||||||
};
|
};
|
||||||
|
|
||||||
delete metadata.matched;
|
delete metadata.presentInClientRouter;
|
||||||
|
|
||||||
// Handle redirects
|
// Handle redirects
|
||||||
if (typeof redirectTo === 'string') {
|
if (typeof redirectTo === 'string') {
|
||||||
@ -246,8 +246,8 @@ async function* handleSSGRoute(
|
|||||||
if (!getPrerenderParams) {
|
if (!getPrerenderParams) {
|
||||||
yield {
|
yield {
|
||||||
error:
|
error:
|
||||||
`The '${stripLeadingSlash(currentRoutePath)}' route uses prerendering and includes parameters, but 'getPrerenderParams' is missing. ` +
|
`The '${stripLeadingSlash(currentRoutePath)}' route uses prerendering and includes parameters, but 'getPrerenderParams' ` +
|
||||||
`Please define 'getPrerenderParams' function for this route in your server routing configuration ` +
|
`is missing. Please define 'getPrerenderParams' function for this route in your server routing configuration ` +
|
||||||
`or specify a different 'renderMode'.`,
|
`or specify a different 'renderMode'.`,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -442,24 +442,38 @@ export async function getRoutesFromAngularRouterConfig(
|
|||||||
includePrerenderFallbackRoutes,
|
includePrerenderFallbackRoutes,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let seenAppShellRoute: string | undefined;
|
||||||
for await (const result of traverseRoutes) {
|
for await (const result of traverseRoutes) {
|
||||||
if ('error' in result) {
|
if ('error' in result) {
|
||||||
errors.push(result.error);
|
errors.push(result.error);
|
||||||
} else {
|
} else {
|
||||||
|
if (result.renderMode === RenderMode.AppShell) {
|
||||||
|
if (seenAppShellRoute !== undefined) {
|
||||||
|
errors.push(
|
||||||
|
`Error: Both '${seenAppShellRoute}' and '${stripLeadingSlash(result.route)}' routes have ` +
|
||||||
|
`their 'renderMode' set to 'AppShell'. AppShell renderMode should only be assigned to one route. ` +
|
||||||
|
`Please review your route configurations to ensure that only one route is set to 'RenderMode.AppShell'.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
seenAppShellRoute = stripLeadingSlash(result.route);
|
||||||
|
}
|
||||||
|
|
||||||
routesResults.push(result);
|
routesResults.push(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverConfigRouteTree) {
|
if (serverConfigRouteTree) {
|
||||||
for (const { route, matched } of serverConfigRouteTree.traverse()) {
|
for (const { route, presentInClientRouter } of serverConfigRouteTree.traverse()) {
|
||||||
if (matched || route === '**') {
|
if (presentInClientRouter || route === '**') {
|
||||||
// Skip if matched or it's the catch-all route.
|
// Skip if matched or it's the catch-all route.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
errors.push(
|
errors.push(
|
||||||
`The server route '${route}' does not match any routes defined in the Angular routing configuration. ` +
|
`The '${route}' server route does not match any routes defined in the Angular ` +
|
||||||
'Please verify and if unneeded remove this route from the server configuration.',
|
`routing configuration (typically provided as a part of the 'provideRouter' call). ` +
|
||||||
|
'Please make sure that the mentioned server route is present in the Angular routing configuration.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ describe('extractRoutesAndCreateRouteTree', () => {
|
|||||||
|
|
||||||
expect(errors).toHaveSize(1);
|
expect(errors).toHaveSize(1);
|
||||||
expect(errors[0]).toContain(
|
expect(errors[0]).toContain(
|
||||||
`The server route 'invalid' does not match any routes defined in the Angular routing configuration`,
|
`The 'invalid' server route does not match any routes defined in the Angular routing configuration`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -339,4 +339,26 @@ describe('extractRoutesAndCreateRouteTree', () => {
|
|||||||
`The 'invalid' route does not match any route defined in the server routing configuration`,
|
`The 'invalid' route does not match any route defined in the server routing configuration`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it(`should error when 'RenderMode.AppShell' is used on more than one route`, async () => {
|
||||||
|
setAngularAppTestingManifest(
|
||||||
|
[
|
||||||
|
{ path: 'home', component: DummyComponent },
|
||||||
|
{ path: 'shell', component: DummyComponent },
|
||||||
|
],
|
||||||
|
[{ path: '**', renderMode: RenderMode.AppShell }],
|
||||||
|
);
|
||||||
|
|
||||||
|
const { errors } = await extractRoutesAndCreateRouteTree(
|
||||||
|
url,
|
||||||
|
/** manifest */ undefined,
|
||||||
|
/** invokeGetPrerenderParams */ false,
|
||||||
|
/** includePrerenderFallbackRoutes */ false,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(errors).toHaveSize(1);
|
||||||
|
expect(errors[0]).toContain(
|
||||||
|
`Both 'home' and 'shell' routes have their 'renderMode' set to 'AppShell'.`,
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user