Skip to content

Commit

Permalink
fix(@angular/build): use named export reqHandler for server.ts requ…
Browse files Browse the repository at this point in the history
…est handling

Some cloud providers, such as Cloudflare, expect the default export to follow a specific structure (e.g., an object with a `fetch` property). To prevent the need for creating a separate `server.ts` file for production builds, the request handler is now exported as `reqHandler` instead of a default export.
  • Loading branch information
alan-agius4 committed Oct 10, 2024
1 parent 01f7475 commit bfa8fec
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,18 @@ export async function createAngularSsrExternalMiddleware(
next: Connect.NextFunction,
) {
(async () => {
const { default: handler, AngularAppEngine } = (await server.ssrLoadModule(
'./server.mjs',
)) as {
default?: unknown;
const { reqHandler, AngularAppEngine } = (await server.ssrLoadModule('./server.mjs')) as {
reqHandler?: unknown;
AngularAppEngine: typeof SSRAngularAppEngine;
};

if (!isSsrNodeRequestHandler(handler) && !isSsrRequestHandler(handler)) {
if (!isSsrNodeRequestHandler(reqHandler) && !isSsrRequestHandler(reqHandler)) {
if (!fallbackWarningShown) {
// eslint-disable-next-line no-console
console.warn(
`The default export in 'server.ts' does not provide a Node.js request handler. ` +
`The 'reqHandler' export in 'server.ts' is either undefined or does not provide a recognized request handler. ` +
'Using the internal SSR middleware instead.',
);

fallbackWarningShown = true;
}

Expand All @@ -130,10 +128,10 @@ export async function createAngularSsrExternalMiddleware(
}

// Forward the request to the middleware in server.ts
if (isSsrNodeRequestHandler(handler)) {
await handler(req, res, next);
if (isSsrNodeRequestHandler(reqHandler)) {
await reqHandler(req, res, next);
} else {
const webRes = await handler(createWebRequestFromNodeRequest(req));
const webRes = await reqHandler(createWebRequestFromNodeRequest(req));
if (!webRes) {
next();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@ export const DEFAULT_URL = new URL('http://ng-localhost/');
* @returns A promise that resolves to the URL of the running server.
*/
export async function launchServer(): Promise<URL> {
const { default: handler } = await loadEsmModuleFromMemory('./server.mjs');
const { reqHandler } = await loadEsmModuleFromMemory('./server.mjs');
const { createWebRequestFromNodeRequest, writeResponseToNodeResponse } =
await loadEsmModule<typeof import('@angular/ssr/node')>('@angular/ssr/node');

if (!isSsrNodeRequestHandler(handler) && !isSsrRequestHandler(handler)) {
if (!isSsrNodeRequestHandler(reqHandler) && !isSsrRequestHandler(reqHandler)) {
return DEFAULT_URL;
}

const server = createServer((req, res) => {
(async () => {
// handle request
if (isSsrNodeRequestHandler(handler)) {
await handler(req, res, (e) => {
if (isSsrNodeRequestHandler(reqHandler)) {
await reqHandler(req, res, (e) => {
throw e;
});
} else {
const webRes = await handler(createWebRequestFromNodeRequest(req));
const webRes = await reqHandler(createWebRequestFromNodeRequest(req));
if (webRes) {
await writeResponseToNodeResponse(webRes, res);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface MainServerBundleExports {
* Represents the exports available from the server bundle.
*/
interface ServerBundleExports {
default: unknown;
reqHandler?: unknown;
}

export function loadEsmModuleFromMemory(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,21 @@ const browserDistFolder = resolve(serverDistFolder, '../<%= browserDistDirectory
const app = express();
const angularApp = new AngularNodeAppEngine();

// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
/**
* Example Express Rest API endpoints can be defined here.
* Uncomment and define endpoints as necessary.
*
* Example:
* ```ts
* app.get('/api/**', (req, res) => {
* // Handle API request
* });
* ```
*/

// Serve static files from /<%= browserDistDirectory %>
/**
* Serve static files from /<%= browserDistDirectory %>
*/
app.get(
'**',
express.static(browserDistFolder, {
Expand All @@ -32,18 +43,30 @@ app.get(
}),
);

/**
* Handle all other requests by rendering the Angular application.
*/
app.get('**', (req, res, next) => {
angularApp
.render(req)
.then((response) => (response ? writeResponseToNodeResponse(response, res) : next()))
.then((response) =>
response ? writeResponseToNodeResponse(response, res) : next(),
)
.catch(next);
});

/**
* Start the server if this module is the main entry point.
* The server listens on the port defined by the `PORT` environment variable, or defaults to 4000.
*/
if (isMainModule(import.meta.url)) {
const port = process.env['PORT'] || 4000;
app.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}

export default createNodeRequestHandler(app);
/**
* The request handler used by the Angular CLI (dev-server and during build).
*/
export const reqHandler = createNodeRequestHandler(app);
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ export default async function () {
);
app.use(router);
const handler = toWebHandler(app);
export default createRequestHandler(handler);
export const reqHandler = createRequestHandler(toWebHandler(app));
`,
});
// Generate components for the above routes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export default async function () {
});
}
export default createNodeRequestHandler(server);
export const reqHandler = createNodeRequestHandler(server);
`,
});

Expand Down
2 changes: 1 addition & 1 deletion tests/legacy-cli/e2e/tests/vite/ssr-entry-express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export default async function () {
});
}
export default createNodeRequestHandler(server);
export const reqHandler = createNodeRequestHandler(server);
`,
});

Expand Down
2 changes: 1 addition & 1 deletion tests/legacy-cli/e2e/tests/vite/ssr-entry-fastify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default async function () {
});
}
export default createNodeRequestHandler(async (req, res) => {
export const reqHandler = createNodeRequestHandler(async (req, res) => {
await server.ready();
server.server.emit('request', req, res);
});
Expand Down
4 changes: 2 additions & 2 deletions tests/legacy-cli/e2e/tests/vite/ssr-entry-h3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ export default async function () {
}
const server = app();
const handler = toWebHandler(server);
export default createRequestHandler(handler);
export const reqHandler = createRequestHandler(toWebHandler(server));
`,
});

Expand Down
2 changes: 1 addition & 1 deletion tests/legacy-cli/e2e/tests/vite/ssr-entry-hono.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export default async function () {
}
const server = app();
export default createRequestHandler(server.fetch);
export const reqHandler = createRequestHandler(server.fetch);
`,
});

Expand Down

0 comments on commit bfa8fec

Please sign in to comment.