Skip to content

Commit d7d8067

Browse files
committed
[DURACOM-247] Refactoring SSR configuration in order to align it with new nomenclature
1 parent 7b1f264 commit d7d8067

10 files changed

Lines changed: 90 additions & 114 deletions

server.ts

Lines changed: 49 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import 'zone.js/node';
1919
import 'reflect-metadata';
20-
import 'rxjs';
2120

2221
/* eslint-disable import/no-namespace */
2322
import * as morgan from 'morgan';
@@ -40,26 +39,25 @@ import { join } from 'path';
4039
import { enableProdMode } from '@angular/core';
4140

4241

43-
4442
import { environment } from './src/environments/environment';
4543
import { createProxyMiddleware } from 'http-proxy-middleware';
46-
import { hasNoValue, hasValue } from './src/app/shared/empty.util';
47-
44+
import { hasValue } from './src/app/shared/empty.util';
4845
import { UIServerConfig } from './src/config/ui-server-config.interface';
49-
5046
import bootstrap from './src/main.server';
51-
5247
import { buildAppConfig } from './src/config/config.server';
53-
import { APP_CONFIG, AppConfig } from './src/config/app-config.interface';
48+
import {
49+
APP_CONFIG,
50+
AppConfig,
51+
} from './src/config/app-config.interface';
5452
import { extendEnvironmentWithAppConfig } from './src/config/config.util';
5553
import { logStartupMessage } from './startup-message';
5654
import { TOKENITEM } from './src/app/core/auth/models/auth-token-info.model';
5755
import { CommonEngine } from '@angular/ssr';
5856
import { APP_BASE_HREF } from '@angular/common';
59-
import { REQUEST, RESPONSE } from './src/express.tokens';
60-
import { dirname, resolve } from 'node:path';
61-
import { fileURLToPath } from 'node:url';
62-
57+
import {
58+
REQUEST,
59+
RESPONSE,
60+
} from './src/express.tokens';
6361

6462
/*
6563
* Set path for the browser application's dist folder
@@ -92,9 +90,6 @@ export function app() {
9290
* Create a new express application
9391
*/
9492
const server = express();
95-
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
96-
const browserDistFolder = resolve(serverDistFolder, '../browser');
97-
const commonEngine = new CommonEngine();
9893

9994
// Tell Express to trust X-FORWARDED-* headers from proxies
10095
// See https://expressjs.com/en/guide/behind-proxies.html
@@ -134,27 +129,6 @@ export function app() {
134129
*/
135130
server.use(json());
136131

137-
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
138-
/* server.engine('html', (_, options, callback) =>
139-
ngExpressEngine({
140-
bootstrap,
141-
providers: [
142-
{
143-
provide: REQUEST,
144-
useValue: (options as any).req,
145-
},
146-
{
147-
provide: RESPONSE,
148-
useValue: (options as any).req.res,
149-
},
150-
{
151-
provide: APP_CONFIG,
152-
useValue: environment,
153-
},
154-
],
155-
})(_, (options as any), callback),
156-
);*/
157-
158132
server.engine('ejs', ejs.renderFile);
159133

160134
/*
@@ -234,12 +208,7 @@ export function app() {
234208
* copy of the page (see cacheCheck())
235209
*/
236210
router.get('*', cacheCheck, ngApp);
237-
// All regular routes use the Angular engine
238-
// server.get('*', (req, res, next) => {
239-
// const { protocol, originalUrl, baseUrl, headers } = req;
240-
//
241-
//
242-
// });
211+
243212
server.use(environment.ui.nameSpace, router);
244213

245214
return server;
@@ -249,7 +218,7 @@ export function app() {
249218
* The callback function to serve server side angular
250219
*/
251220
function ngApp(req, res, next) {
252-
if (environment.universal.preboot) {
221+
if (environment.ssr.enabled) {
253222
// Render the page to user via SSR (server side rendering)
254223
serverSideRender(req, res, next);
255224
} else {
@@ -264,17 +233,19 @@ function ngApp(req, res, next) {
264233
* returned to the user.
265234
* @param req current request
266235
* @param res current response
236+
* @param next the next function
267237
* @param sendToUser if true (default), send the rendered content to the user.
268238
* If false, then only save this rendered content to the in-memory cache (to refresh cache).
269239
*/
270240
function serverSideRender(req, res, next, sendToUser: boolean = true) {
271241
const { protocol, originalUrl, baseUrl, headers } = req;
272-
const commonEngine = new CommonEngine();
242+
const commonEngine = new CommonEngine({ enablePerformanceProfiler: environment.ssr.enablePerformanceProfiler });
273243
// Render the page via SSR (server side rendering)
274244
commonEngine
275245
.render({
276246
bootstrap,
277247
documentFilePath: indexHtml,
248+
inlineCriticalCss: environment.ssr.inlineCriticalCss,
278249
url: `${protocol}://${headers.host}${originalUrl}`,
279250
publicPath: DIST_FOLDER,
280251
providers: [
@@ -293,44 +264,35 @@ function serverSideRender(req, res, next, sendToUser: boolean = true) {
293264
},
294265
],
295266
})
296-
.then((html) => res.send(html))
297-
.catch((err) => next(err));
298-
299-
300-
/* res.render(indexHtml, {
301-
req,
302-
res,
303-
preboot: environment.universal.preboot,
304-
async: environment.universal.async,
305-
time: environment.universal.time,
306-
baseUrl: environment.ui.nameSpace,
307-
originUrl: environment.ui.baseUrl,
308-
requestUrl: req.originalUrl,
309-
}, (err, data) => {
310-
if (hasNoValue(err) && hasValue(data)) {
311-
// save server side rendered page to cache (if any are enabled)
312-
saveToCache(req, data);
313-
if (sendToUser) {
314-
res.locals.ssr = true; // mark response as SSR (enables text compression)
315-
// send rendered page to user
316-
res.send(data);
317-
}
318-
} else if (hasValue(err) && err.code === 'ERR_HTTP_HEADERS_SENT') {
319-
// When this error occurs we can't fall back to CSR because the response has already been
320-
// sent. These errors occur for various reasons in universal, not all of which are in our
321-
// control to solve.
322-
console.warn('Warning [ERR_HTTP_HEADERS_SENT]: Tried to set headers after they were sent to the client');
323-
} else {
324-
console.warn('Error in server-side rendering (SSR)');
325-
if (hasValue(err)) {
326-
console.warn('Error details : ', err);
267+
.then((html) => {
268+
if (hasValue(html)) {
269+
// save server side rendered page to cache (if any are enabled)
270+
saveToCache(req, html);
271+
if (sendToUser) {
272+
res.locals.ssr = true; // mark response as SSR (enables text compression)
273+
// send rendered page to user
274+
res.send(html);
275+
}
327276
}
328-
if (sendToUser) {
329-
console.warn('Falling back to serving direct client-side rendering (CSR).');
330-
clientSideRender(req, res);
277+
})
278+
.catch((err) => {
279+
if (hasValue(err) && err.code === 'ERR_HTTP_HEADERS_SENT') {
280+
// When this error occurs we can't fall back to CSR because the response has already been
281+
// sent. These errors occur for various reasons in universal, not all of which are in our
282+
// control to solve.
283+
console.warn('Warning [ERR_HTTP_HEADERS_SENT]: Tried to set headers after they were sent to the client');
284+
} else {
285+
console.warn('Error in server-side rendering (SSR)');
286+
if (hasValue(err)) {
287+
console.warn('Error details : ', err);
288+
}
289+
if (sendToUser) {
290+
console.warn('Falling back to serving direct client-side rendering (CSR).');
291+
clientSideRender(req, res);
292+
}
331293
}
332-
}
333-
});*/
294+
next(err);
295+
});
334296
}
335297

336298
/**
@@ -388,7 +350,7 @@ function initCache() {
388350
function botCacheEnabled(): boolean {
389351
// Caching is only enabled if SSR is enabled AND
390352
// "max" pages to cache is greater than zero
391-
return environment.universal.preboot && environment.cache.serverSide.botCache.max && (environment.cache.serverSide.botCache.max > 0);
353+
return environment.ssr.enabled && environment.cache.serverSide.botCache.max && (environment.cache.serverSide.botCache.max > 0);
392354
}
393355

394356
/**
@@ -397,7 +359,7 @@ function botCacheEnabled(): boolean {
397359
function anonymousCacheEnabled(): boolean {
398360
// Caching is only enabled if SSR is enabled AND
399361
// "max" pages to cache is greater than zero
400-
return environment.universal.preboot && environment.cache.serverSide.anonymousCache.max && (environment.cache.serverSide.anonymousCache.max > 0);
362+
return environment.ssr.enabled && environment.cache.serverSide.anonymousCache.max && (environment.cache.serverSide.anonymousCache.max > 0);
401363
}
402364

403365
/**
@@ -410,9 +372,9 @@ function cacheCheck(req, res, next) {
410372

411373
// If the bot cache is enabled and this request looks like a bot, check the bot cache for a cached page.
412374
if (botCacheEnabled() && isbot(req.get('user-agent'))) {
413-
cachedCopy = checkCacheForRequest('bot', botCache, req, res);
375+
cachedCopy = checkCacheForRequest('bot', botCache, req, res, next);
414376
} else if (anonymousCacheEnabled() && !isUserAuthenticated(req)) {
415-
cachedCopy = checkCacheForRequest('anonymous', anonymousCache, req, res);
377+
cachedCopy = checkCacheForRequest('anonymous', anonymousCache, req, res, next);
416378
}
417379

418380
// If cached copy exists, return it to the user.
@@ -448,9 +410,10 @@ function cacheCheck(req, res, next) {
448410
* @param cache LRU cache to check
449411
* @param req current request to look for in the cache
450412
* @param res current response
413+
* @param next the next function
451414
* @returns cached copy (if found) or undefined (if not found)
452415
*/
453-
function checkCacheForRequest(cacheName: string, cache: LRU<string, any>, req, res): any {
416+
function checkCacheForRequest(cacheName: string, cache: LRU<string, any>, req, res, next): any {
454417
// Get the cache key for this request
455418
const key = getCacheKey(req);
456419

@@ -466,7 +429,7 @@ function checkCacheForRequest(cacheName: string, cache: LRU<string, any>, req, r
466429
// Update cached copy by rerendering server-side
467430
// NOTE: In this scenario the currently cached copy will be returned to the current user.
468431
// This re-render is peformed behind the scenes to update cached copy for next user.
469-
serverSideRender(req, res, null, false);
432+
serverSideRender(req, res, next, false);
470433
}
471434
} else {
472435
if (environment.cache.serverSide.debug) { console.log(`CACHE MISS FOR ${key} in ${cacheName} cache.`); }
@@ -570,7 +533,7 @@ function createHttpsServer(keys) {
570533
const listener = createServer({
571534
key: keys.serviceKey,
572535
cert: keys.certificate,
573-
}, app).listen(environment.ui.port, environment.ui.host, () => {
536+
}, app()).listen(environment.ui.port, environment.ui.host, () => {
574537
serverStarted();
575538
});
576539

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AppConfig } from './app-config.interface';
2-
import { UniversalConfig } from './universal-config.interface';
2+
import { SSRConfig } from './ssr-config.interface';
33

44
export interface BuildConfig extends AppConfig {
5-
universal: UniversalConfig;
5+
ssr: SSRConfig;
66
}

src/config/default-app-config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class DefaultAppConfig implements AppConfig {
3434
// NOTE: will log all redux actions and transfers in console
3535
debug = false;
3636

37-
// Angular Universal server settings
37+
// Angular express server settings
3838
// NOTE: these must be 'synced' with the 'dspace.ui.url' setting in your backend's local.cfg.
3939
ui: UIServerConfig = {
4040
ssl: false,

src/config/ssr-config.interface.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Config } from './config.interface';
2+
3+
export interface SSRConfig extends Config {
4+
/**
5+
* A boolean flag indicating whether the SSR configuration is enabled
6+
* Defaults to true.
7+
*/
8+
enabled: boolean;
9+
10+
/**
11+
* Enable request performance profiling data collection and printing the results in the server console.
12+
* Defaults to false.
13+
*/
14+
enablePerformanceProfiler: boolean;
15+
16+
/**
17+
* Reduce render blocking requests by inlining critical CSS.
18+
* Defaults to true.
19+
*/
20+
inlineCriticalCss: boolean;
21+
}

src/config/store/devtools.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ export const StoreDevModules = [
66
StoreDevtoolsModule.instrument({
77
maxAge: 1000,
88
logOnly: false,
9-
connectInZone: true}),
9+
connectInZone: true }),
1010
];

src/config/universal-config.interface.ts

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

src/environments/environment.production.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { BuildConfig } from '../config/build-config.interface';
33
export const environment: Partial<BuildConfig> = {
44
production: true,
55

6-
// Angular Universal settings
7-
universal: {
8-
preboot: true,
9-
async: true,
10-
time: false,
6+
// Angular SSR settings
7+
ssr: {
8+
enabled: true,
9+
enablePerformanceProfiler: false,
10+
inlineCriticalCss: true,
1111
},
1212
};

src/environments/environment.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import { NotificationAnimationsType } from '../app/shared/notifications/models/n
77
export const environment: BuildConfig = {
88
production: false,
99

10-
// Angular Universal settings
11-
universal: {
12-
preboot: true,
13-
async: true,
14-
time: false,
10+
// Angular SSR settings
11+
ssr: {
12+
enabled: true,
13+
enablePerformanceProfiler: false,
14+
inlineCriticalCss: true,
1515
},
1616

17-
// Angular Universal server settings.
17+
// Angular express server settings.
1818
ui: {
1919
ssl: false,
2020
host: 'dspace.com',

src/environments/environment.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import { BuildConfig } from '../config/build-config.interface';
88
export const environment: Partial<BuildConfig> = {
99
production: false,
1010

11-
// Angular Universal settings
12-
universal: {
13-
preboot: false,
14-
async: true,
15-
time: false,
11+
// Angular SSR settings
12+
ssr: {
13+
enabled: false,
14+
enablePerformanceProfiler: false,
15+
inlineCriticalCss: true,
1616
},
1717
};
1818

src/main.server.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,4 @@ import { serverAppConfig } from './modules/app/server-app.config';
1414

1515
const bootstrap = () => bootstrapApplication(AppComponent, serverAppConfig);
1616

17-
export { renderModule } from '@angular/platform-server';
1817
export default bootstrap;

0 commit comments

Comments
 (0)