Skip to content

Commit e9b057b

Browse files
committed
refactor(@angular/build): remove route extractor and use version from @angular/ssr
Removed the route extractor from `@angular/build` and replaced it with the one from `@angular/ssr` for consistency and improved maintenance.
1 parent dcbdb8b commit e9b057b

File tree

21 files changed

+123
-266
lines changed

21 files changed

+123
-266
lines changed

packages/angular/build/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ ts_library(
5555
module_name = "@angular/build",
5656
module_root = "src/index.d.ts",
5757
deps = [
58-
"//packages/angular/build/src/utils/routes-extractor",
58+
"//packages/angular/ssr",
5959
"//packages/angular_devkit/architect",
6060
"@npm//@ampproject/remapping",
6161
"@npm//@angular/common",

packages/angular/build/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"@angular/localize": "^18.0.0 || ^18.2.0-next.0",
5050
"@angular/platform-server": "^18.0.0 || ^18.2.0-next.0",
5151
"@angular/service-worker": "^18.0.0 || ^18.2.0-next.0",
52+
"@angular/ssr": "^0.0.0-PLACEHOLDER",
5253
"less": "^4.2.0",
5354
"postcss": "^8.4.0",
5455
"tailwindcss": "^2.0.0 || ^3.0.0",
@@ -64,6 +65,9 @@
6465
"@angular/service-worker": {
6566
"optional": true
6667
},
68+
"@angular/ssr": {
69+
"optional": true
70+
},
6771
"less": {
6872
"optional": true
6973
},

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
import type { BuildOptions, PartialMessage } from 'esbuild';
1010
import assert from 'node:assert';
1111
import { createHash } from 'node:crypto';
12-
import { readFile } from 'node:fs/promises';
13-
import { extname, join } from 'node:path';
12+
import { extname } from 'node:path';
1413
import type { NormalizedApplicationBuildOptions } from '../../builders/application/options';
1514
import { allowMangle } from '../../utils/environment-options';
1615
import { createCompilerPlugin } from './angular/compiler-plugin';
@@ -246,14 +245,7 @@ export function createServerCodeBundleOptions(
246245
}
247246

248247
if (prerenderOptions?.discoverRoutes) {
249-
// We do not import it directly so that node.js modules are resolved using the correct context.
250-
const routesExtractorCode = await readFile(
251-
join(__dirname, '../../utils/routes-extractor/extractor.js'),
252-
'utf-8',
253-
);
254-
255-
// Remove source map URL comments from the code if a sourcemap is present as this will not match the file.
256-
contents.push(routesExtractorCode.replace(/^\/\/# sourceMappingURL=[^\r\n]*/gm, ''));
248+
contents.push(`export { ɵgetRoutesFromAngularRouterConfig } from '@angular/ssr';`);
257249
}
258250

259251
return {

packages/angular/build/src/utils/routes-extractor/BUILD.bazel

Lines changed: 0 additions & 26 deletions
This file was deleted.

packages/angular/build/src/utils/routes-extractor/extractor.ts

Lines changed: 0 additions & 141 deletions
This file was deleted.

packages/angular/build/src/utils/server-rendering/main-bundle-exports.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import type { ApplicationRef, Type, ɵConsole } from '@angular/core';
1010
import type { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/platform-server';
11-
import type { extractRoutes } from '../routes-extractor/extractor';
11+
import type { ɵgetRoutesFromAngularRouterConfig } from '@angular/ssr';
1212

1313
export interface MainServerBundleExports {
1414
/** Standalone application bootstrapping function. */
@@ -26,7 +26,7 @@ export interface RenderUtilsServerBundleExports {
2626
renderApplication: typeof renderApplication;
2727

2828
/** Method to extract routes from the router config. */
29-
extractRoutes: typeof extractRoutes;
29+
ɵgetRoutesFromAngularRouterConfig: typeof ɵgetRoutesFromAngularRouterConfig;
3030

3131
ɵresetCompiledComponents?: () => void;
3232

packages/angular/build/src/utils/server-rendering/routes-extractor-worker.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,27 @@ const { document, verbose } = workerData as RoutesExtractorWorkerData;
2929

3030
/** Renders an application based on a provided options. */
3131
async function extractRoutes(): Promise<RoutersExtractorWorkerResult> {
32-
const { extractRoutes } = await loadEsmModuleFromMemory('./render-utils.server.mjs');
32+
const { ɵgetRoutesFromAngularRouterConfig: getRoutesFromAngularRouterConfig } =
33+
await loadEsmModuleFromMemory('./render-utils.server.mjs');
3334
const { default: bootstrapAppFnOrModule } = await loadEsmModuleFromMemory('./main.server.mjs');
3435

3536
const skippedRedirects: string[] = [];
3637
const skippedOthers: string[] = [];
3738
const routes: string[] = [];
3839

39-
for await (const { route, success, redirect } of extractRoutes(
40+
const { routes: extractRoutes } = await getRoutesFromAngularRouterConfig(
4041
bootstrapAppFnOrModule,
4142
document,
42-
)) {
43-
if (success) {
44-
routes.push(route);
45-
continue;
46-
}
43+
new URL('http://localhost'),
44+
);
4745

48-
if (redirect) {
46+
for (const { route, redirectTo } of extractRoutes) {
47+
if (redirectTo !== undefined) {
4948
skippedRedirects.push(route);
50-
} else {
49+
} else if (/[:*]/.test(route)) {
5150
skippedOthers.push(route);
51+
} else {
52+
routes.push(route);
5253
}
5354
}
5455

packages/angular/ssr/public_api.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,4 @@ export {
1212
type CommonEngineOptions,
1313
} from './src/common-engine/common-engine';
1414

15-
// TODO(alanagius): enable at a later stage
16-
// export { AngularAppEngine } from './src/app-engine';
17-
// export { AngularServerApp } from './src/app';
18-
// export { REQUEST, REQUEST_CONTEXT, RESPONSE_INIT } from './src/tokens';
15+
export { getRoutesFromAngularRouterConfig as ɵgetRoutesFromAngularRouterConfig } from './src/routes/ng-routes';

packages/angular/ssr/src/routes/ng-routes.ts

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,24 @@ interface AngularRouterConfigResult {
3737
baseHref: string;
3838

3939
/**
40-
* An async iterator that yields `RouteResult` objects.
40+
* An array of `RouteResult` objects representing the application's routes.
4141
*
42-
* Each `RouteResult` represents a route and its associated information, such as the path
43-
* and any potential redirection target.
42+
* Each `RouteResult` contains details about a specific route, such as its path and any
43+
* associated redirection targets. This array is asynchronously generated and
44+
* provides information on how routes are structured and resolved.
45+
*
46+
* Example:
47+
* ```typescript
48+
* const result: AngularRouterConfigResult = {
49+
* baseHref: '/app/',
50+
* routes: [
51+
* { route: '/home', redirectTo: '/welcome' },
52+
* { route: '/about' },
53+
* ],
54+
* };
55+
* ```
4456
*/
45-
routes: AsyncIterableIterator<RouteResult>;
57+
routes: RouteResult[];
4658
}
4759

4860
/**
@@ -211,28 +223,34 @@ export async function getRoutesFromAngularRouterConfig(
211223

212224
const injector = applicationRef.injector;
213225
const router = injector.get(Router);
226+
const routesResults: RouteResult[] = [];
214227

215-
const baseHref =
216-
injector.get(APP_BASE_HREF, null, { optional: true }) ??
217-
injector.get(PlatformLocation).getBaseHrefFromDOM();
218-
219-
if (router.config.length === 0) {
220-
// No routes found in the configuration.
221-
return { baseHref, routes: (async function* () {})() };
222-
} else {
228+
if (router.config.length) {
223229
const compiler = injector.get(Compiler);
224230

225231
// Retrieve all routes from the Angular router configuration.
226-
return {
227-
baseHref,
228-
routes: traverseRoutesConfig({
229-
routes: router.config,
230-
compiler,
231-
parentInjector: injector,
232-
parentRoute: '',
233-
}),
234-
};
232+
const traverseRoutes = traverseRoutesConfig({
233+
routes: router.config,
234+
compiler,
235+
parentInjector: injector,
236+
parentRoute: '',
237+
});
238+
239+
for await (const result of traverseRoutes) {
240+
routesResults.push(result);
241+
}
242+
} else {
243+
routesResults.push({ route: '' });
235244
}
245+
246+
const baseHref =
247+
injector.get(APP_BASE_HREF, null, { optional: true }) ??
248+
injector.get(PlatformLocation).getBaseHrefFromDOM();
249+
250+
return {
251+
baseHref,
252+
routes: routesResults,
253+
};
236254
} finally {
237255
platformRef.destroy();
238256
}

packages/angular/ssr/src/routes/router.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class ServerRouter {
6565
url,
6666
);
6767

68-
for await (let { route, redirectTo } of routes) {
68+
for (let { route, redirectTo } of routes) {
6969
route = joinUrlParts(baseHref, route);
7070
redirectTo = redirectTo === undefined ? undefined : joinUrlParts(baseHref, redirectTo);
7171

packages/angular/ssr/src/utils/ng.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,5 @@ export function renderAngular(
6666
* @returns True if the value is an Angular module (i.e., it has the `ɵmod` property), false otherwise.
6767
*/
6868
export function isNgModule(value: AngularBootstrap): value is Type<unknown> {
69-
return typeof value === 'object' && 'ɵmod' in value;
69+
return 'ɵmod' in value;
7070
}

packages/angular_devkit/build_angular/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ ts_library(
123123
deps = [
124124
"//packages/angular/build",
125125
"//packages/angular/build:private",
126+
"//packages/angular/ssr",
126127
"//packages/angular_devkit/architect",
127128
"//packages/angular_devkit/build_webpack",
128129
"//packages/angular_devkit/core",

0 commit comments

Comments
 (0)