Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion goldens/public-api/angular/ssr/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,36 @@

```ts

import { EnvironmentProviders } from '@angular/core';

// @public
export class AngularAppEngine {
getHeaders(request: Request): ReadonlyMap<string, string>;
getPrerenderHeaders(request: Request): ReadonlyMap<string, string>;
render(request: Request, requestContext?: unknown): Promise<Response | null>;
static ɵhooks: Hooks;
}

// @public
export enum PrerenderFallback {
Client = 1,
None = 2,
Server = 0
}

// @public
export function provideServerRoutesConfig(routes: ServerRoute[]): EnvironmentProviders;

// @public
export enum RenderMode {
AppShell = 0,
Client = 2,
Prerender = 3,
Server = 1
}

// @public
export type ServerRoute = ServerRouteAppShell | ServerRouteClient | ServerRoutePrerender | ServerRoutePrerenderWithParams | ServerRouteServer;

// (No @packageDocumentation comment for this package)

```
43 changes: 43 additions & 0 deletions goldens/public-api/angular/ssr/index_transitive.api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## API Report File for "@angular/devkit-repo"

> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).

```ts

// @public
export interface ServerRouteAppShell extends Omit<ServerRouteCommon, 'headers' | 'status'> {
renderMode: RenderMode.AppShell;
}

// @public
export interface ServerRouteClient extends ServerRouteCommon {
renderMode: RenderMode.Client;
}

// @public
export interface ServerRouteCommon {
headers?: Record<string, string>;
path: string;
status?: number;
}

// @public
export interface ServerRoutePrerender extends Omit<ServerRouteCommon, 'status'> {
fallback?: never;
renderMode: RenderMode.Prerender;
}

// @public
export interface ServerRoutePrerenderWithParams extends Omit<ServerRoutePrerender, 'fallback'> {
fallback?: PrerenderFallback;
getPrerenderParams: () => Promise<Record<string, string>[]>;
}

// @public
export interface ServerRouteServer extends ServerRouteCommon {
renderMode: RenderMode.Server;
}

// (No @packageDocumentation comment for this package)

```
2 changes: 1 addition & 1 deletion goldens/public-api/angular/ssr/node/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Type } from '@angular/core';

// @public
export class AngularNodeAppEngine {
getHeaders(request: IncomingMessage): ReadonlyMap<string, string>;
getPrerenderHeaders(request: IncomingMessage): ReadonlyMap<string, string>;
render(request: IncomingMessage, requestContext?: unknown): Promise<Response | null>;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
harness.expectFile('dist/browser/main.js').toExist();
const indexFileContent = harness.expectFile('dist/browser/index.html').content;
indexFileContent.toContain('app-shell works!');
indexFileContent.toContain('ng-server-context="app-shell"');
// TODO(alanagius): enable once integration of routes in complete.
// indexFileContent.toContain('ng-server-context="app-shell"');
});

it('critical CSS is inlined', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,6 @@ export function createServerMainCodeBundleOptions(

// Add @angular/ssr exports
`export {
ɵServerRenderContext,
ɵdestroyAngularServerApp,
ɵextractRoutesAndCreateRouteTree,
ɵgetOrCreateAngularServerApp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
*/

import type { ApplicationRef, Type } from '@angular/core';
import type {
ɵServerRenderContext,
ɵextractRoutesAndCreateRouteTree,
ɵgetOrCreateAngularServerApp,
} from '@angular/ssr';
import type { ɵextractRoutesAndCreateRouteTree, ɵgetOrCreateAngularServerApp } from '@angular/ssr';
import { assertIsError } from '../error';
import { loadEsmModule } from '../load-esm';

Expand All @@ -20,7 +16,6 @@ import { loadEsmModule } from '../load-esm';
*/
interface MainServerBundleExports {
default: (() => Promise<ApplicationRef>) | Type<unknown>;
ɵServerRenderContext: typeof ɵServerRenderContext;
ɵextractRoutesAndCreateRouteTree: typeof ɵextractRoutesAndCreateRouteTree;
ɵgetOrCreateAngularServerApp: typeof ɵgetOrCreateAngularServerApp;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,13 @@ async function renderPages(
route.slice(baseHrefWithLeadingSlash.length - 1),
);

const isAppShellRoute = appShellRoute === routeWithoutBaseHref;
const render: Promise<string | null> = renderWorker.run({ url: route, isAppShellRoute });
const render: Promise<string | null> = renderWorker.run({ url: route });
const renderResult: Promise<void> = render
.then((content) => {
if (content !== null) {
const outPath = posix.join(removeLeadingSlash(routeWithoutBaseHref), 'index.html');
const isAppShellRoute = appShellRoute === routeWithoutBaseHref;

output[outPath] = { content, appShellRoute: isAppShellRoute };
}
})
Expand Down
18 changes: 6 additions & 12 deletions packages/angular/build/src/utils/server-rendering/render-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,18 @@ export interface RenderWorkerData extends ESMInMemoryFileLoaderWorkerData {

export interface RenderOptions {
url: string;
isAppShellRoute: boolean;
}

/**
* Renders each route in routes and writes them to <outputPath>/<route>/index.html.
*/
async function renderPage({ url, isAppShellRoute }: RenderOptions): Promise<string | null> {
const {
ɵgetOrCreateAngularServerApp: getOrCreateAngularServerApp,
ɵServerRenderContext: ServerRenderContext,
} = await loadEsmModuleFromMemory('./main.server.mjs');
async function renderPage({ url }: RenderOptions): Promise<string | null> {
const { ɵgetOrCreateAngularServerApp: getOrCreateAngularServerApp } =
await loadEsmModuleFromMemory('./main.server.mjs');
const angularServerApp = getOrCreateAngularServerApp();
const response = await angularServerApp.render(
new Request(new URL(url, 'http://local-angular-prerender'), {
signal: AbortSignal.timeout(30_000),
}),
undefined,
isAppShellRoute ? ServerRenderContext.AppShell : ServerRenderContext.SSG,
const response = await angularServerApp.renderStatic(
new URL(url, 'http://local-angular-prerender'),
AbortSignal.timeout(30_000),
);

return response ? response.text() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ async function extractRoutes(): Promise<RoutersExtractorWorkerResult> {

const routeTree = await extractRoutesAndCreateRouteTree(
new URL('http://local-angular-prerender/'),
/** manifest */ undefined,
/** invokeGetPrerenderParams */ true,
);

return routeTree.toObject();
Expand Down
12 changes: 11 additions & 1 deletion packages/angular/ssr/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@npm//@angular/build-tooling/bazel/api-golden:index.bzl", "api_golden_test_npm_package")
load("@npm//@angular/build-tooling/bazel/api-golden:index.bzl", "api_golden_test", "api_golden_test_npm_package")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("//tools:defaults.bzl", "ng_package", "ts_library")

Expand Down Expand Up @@ -67,3 +67,13 @@ api_golden_test_npm_package(
golden_dir = "angular_cli/goldens/public-api/angular/ssr",
npm_package = "angular_cli/packages/angular/ssr/npm_package",
)

api_golden_test(
name = "ssr_transitive_api",
data = [
":ssr",
"//goldens:public-api",
],
entry_point = "angular_cli/packages/angular/ssr/public_api_transitive.d.ts",
golden = "angular_cli/goldens/public-api/angular/ssr/index_transitive.api.md",
)
6 changes: 3 additions & 3 deletions packages/angular/ssr/node/src/app-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class AngularNodeAppEngine {
* app.use(express.static('dist/browser', {
* setHeaders: (res, path) => {
* // Retrieve headers for the current request
* const headers = angularAppEngine.getHeaders(res.req);
* const headers = angularAppEngine.getPrerenderHeaders(res.req);
*
* // Apply the retrieved headers to the response
* for (const { key, value } of headers) {
Expand All @@ -66,7 +66,7 @@ export class AngularNodeAppEngine {
}));
* ```
*/
getHeaders(request: IncomingMessage): ReadonlyMap<string, string> {
return this.angularAppEngine.getHeaders(createWebRequestFromNodeRequest(request));
getPrerenderHeaders(request: IncomingMessage): ReadonlyMap<string, string> {
return this.angularAppEngine.getPrerenderHeaders(createWebRequestFromNodeRequest(request));
}
}
1 change: 0 additions & 1 deletion packages/angular/ssr/private_export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export {
extractRoutesAndCreateRouteTree as ɵextractRoutesAndCreateRouteTree,
} from './src/routes/ng-routes';
export {
ServerRenderContext as ɵServerRenderContext,
getOrCreateAngularServerApp as ɵgetOrCreateAngularServerApp,
destroyAngularServerApp as ɵdestroyAngularServerApp,
} from './src/app';
Expand Down
7 changes: 7 additions & 0 deletions packages/angular/ssr/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@
export * from './private_export';

export { AngularAppEngine } from './src/app-engine';

export {
type PrerenderFallback,
type RenderMode,
type ServerRoute,
provideServerRoutesConfig,
} from './src/routes/route-config';
20 changes: 20 additions & 0 deletions packages/angular/ssr/public_api_transitive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/

// This file exports symbols that are not part of the public API but are
// dependencies of public API symbols. Including them here ensures they
// are tracked in the API golden file, preventing accidental breaking changes.

export type {
ServerRouteAppShell,
ServerRouteClient,
ServerRoutePrerender,
ServerRoutePrerenderWithParams,
ServerRouteServer,
ServerRouteCommon,
} from './src/routes/route-config';
2 changes: 1 addition & 1 deletion packages/angular/ssr/src/app-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export class AngularAppEngine {
* @returns A `Map` containing the HTTP headers as key-value pairs.
* @note This function should be used exclusively for retrieving headers of SSG pages.
*/
getHeaders(request: Request): ReadonlyMap<string, string> {
getPrerenderHeaders(request: Request): ReadonlyMap<string, string> {
if (this.manifest.staticPathsHeaders.size === 0) {
return new Map();
}
Expand Down
Loading