mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
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
71 lines
2.3 KiB
TypeScript
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';
|