angular/aio/content/examples/universal-ngmodule/server.ts
Ward Bell 44c7469495 docs: Migrate Universal guide and code to Standalone (#51564)
Heavily reworked with advice from Alan Agius.

FWIW
* `ng test` fails because there are no unit tests
* `yarn e2e` builds but fails - `Unable to start a WebDriver session.`

**Added `readme.md` to sample code**

Makes it easier for the casual downloader to try the example.

**Added `universal-ngmodule`**

The existing ngModule-based doc has a lot of guidance for developers who are still building with NgModule. Given that we are preserving the existing NgModule guidance (with modifications), it seems prudent to preserve the NgModule form of the Universal guidance. So I copied the existing guide and code to `universal-ngmodule` and added it to the left-side navigation under the "NgModules" sub-tree.

Warning: it retains all of the faults of the original guide ... faults that were addressed in the current revision.

PR Close #51564
2023-09-12 12:20:10 -07:00

71 lines
2.3 KiB
TypeScript

import 'zone.js/node';
import { APP_BASE_HREF } from '@angular/common';
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { existsSync } from 'fs';
import { join } from 'path';
import { AppServerModule } from './src/main.server';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
// #docregion ngExpressEngine
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/main/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
// #enddocregion ngExpressEngine
server.set('view engine', 'html');
server.set('views', distFolder);
// #docregion data-request
// TODO: implement data requests securely
server.get('/api/**', (req, res) => {
res.status(404).send('data requests are not yet supported');
});
// #enddocregion data-request
// #docregion static
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// #enddocregion static
// #docregion navigation-request
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
// #enddocregion navigation-request
return server;
}
function run(): void {
const port = process.env['PORT'] || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export * from './src/main.server';