Skip to content

Commit 50af6e6

Browse files
committed
feat: Angular 9
1 parent 30d7b33 commit 50af6e6

File tree

6 files changed

+153
-23
lines changed

6 files changed

+153
-23
lines changed

angular.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
"src/robots.txt",
2424
"src/manifest.json"
2525
],
26-
"styles": [
27-
],
26+
"styles": [],
2827
"scripts": []
2928
},
3029
"configurations": {
@@ -96,8 +95,7 @@
9695
"polyfills": "src/polyfills.ts",
9796
"tsConfig": "src/tsconfig.spec.json",
9897
"scripts": [],
99-
"styles": [
100-
],
98+
"styles": [],
10199
"assets": [
102100
"src/assets",
103101
"src/favicon.ico",
@@ -132,9 +130,9 @@
132130
"replace": "src/environments/environment.ts",
133131
"with": "src/environments/server/environment.ts"
134132
}
135-
]
136-
, "optimization": true
137-
},
133+
],
134+
"optimization": true
135+
},
138136
"production": {
139137
"optimization": true,
140138
"outputHashing": "all",
@@ -214,5 +212,8 @@
214212
"@schematics/angular:directive": {
215213
"prefix": "app"
216214
}
215+
},
216+
"cli": {
217+
"analytics": "64925903-0f96-433a-83be-7a3fb8485063"
217218
}
218-
}
219+
}

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"@ngx-meta/core": "8.0.2",
5555
"@ngx-translate/core": "12.0.0",
5656
"@ngx-translate/http-loader": "4.0.0",
57-
"@gorniv/ngx-universal": "2.2.0",
57+
"@gorniv/ngx-universal": "2.2.2",
5858
"cookie-parser": "1.4.4",
5959
"core-js": "3.6.4",
6060
"express": "^4.15.2",

server.ts.bak renamed to server.bak.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const PORT = process.env.PORT || 4000;
5555
import { ROUTES } from './static.paths';
5656
// for test
5757
import { exit } from 'process';
58-
import { NgxRequest, NgxResponce } from '@gorniv/ngx-universal';
58+
import { NgxRequest, NgxResponse } from '@gorniv/ngx-universal';
5959

6060
enableProdMode();
6161

server.ts

Lines changed: 138 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,155 @@ import { join } from 'path';
77
import { AppServerModule } from './src/main.server';
88
import { APP_BASE_HREF } from '@angular/common';
99
import { existsSync } from 'fs';
10+
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
11+
import { NgxRequest, NgxResponse } from '@gorniv/ngx-universal';
12+
import * as compression from 'compression';
13+
import * as cookieparser from 'cookie-parser';
14+
import { exit } from 'process';
15+
// for debug
16+
require('source-map-support').install();
17+
18+
// for tests
19+
const test = process.env['TEST'] === 'true';
20+
21+
// ssr DOM
22+
const domino = require('domino');
23+
const fs = require('fs');
24+
const path = require('path');
25+
// index from browser build!
26+
const template = fs.readFileSync(path.join('.', 'dist', 'index.html')).toString();
27+
// for mock global window by domino
28+
const win = domino.createWindow(template);
29+
// from server build
30+
const files = fs.readdirSync(`${process.cwd()}/dist-server`);
31+
// mock
32+
global['window'] = win;
33+
// not implemented property and functions
34+
Object.defineProperty(win.document.body.style, 'transform', {
35+
value: () => {
36+
return {
37+
enumerable: true,
38+
configurable: true,
39+
};
40+
},
41+
});
42+
// mock documnet
43+
global['document'] = win.document;
44+
// othres mock
45+
global['CSS'] = null;
46+
// global['XMLHttpRequest'] = require('xmlhttprequest').XMLHttpRequest;
47+
global['Prism'] = null;
1048

1149
// The Express app is exported so that it can be used by serverless Functions.
1250
export function app() {
1351
const server = express();
1452
const distFolder = join(process.cwd(), 'dist');
15-
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
53+
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
54+
? 'index.original.html'
55+
: 'index';
56+
57+
// redirects!
58+
const redirectowww = false;
59+
const redirectohttps = false;
60+
const wwwredirecto = true;
61+
server.use((req, res, next) => {
62+
// for domain/index.html
63+
if (req.url === '/index.html') {
64+
res.redirect(301, 'https://' + req.hostname);
65+
}
66+
67+
// check if it is a secure (https) request
68+
// if not redirect to the equivalent https url
69+
if (
70+
redirectohttps &&
71+
req.headers['x-forwarded-proto'] !== 'https' &&
72+
req.hostname !== 'localhost'
73+
) {
74+
// special for robots.txt
75+
if (req.url === '/robots.txt') {
76+
next();
77+
return;
78+
}
79+
res.redirect(301, 'https://' + req.hostname + req.url);
80+
}
81+
82+
// www or not
83+
if (redirectowww && !req.hostname.startsWith('www.')) {
84+
res.redirect(301, 'https://www.' + req.hostname + req.url);
85+
}
86+
87+
// www or not
88+
if (wwwredirecto && req.hostname.startsWith('www.')) {
89+
const host = req.hostname.slice(4, req.hostname.length);
90+
res.redirect(301, 'https://' + host + req.url);
91+
}
1692

93+
// for test
94+
if (test && req.url === '/test/exit') {
95+
res.send('exit');
96+
exit(0);
97+
return;
98+
}
99+
100+
next();
101+
});
17102
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
18-
server.engine('html', ngExpressEngine({
19-
bootstrap: AppServerModule,
20-
}));
103+
server.engine(
104+
'html',
105+
ngExpressEngine({
106+
bootstrap: AppServerModule,
107+
}),
108+
);
21109

22110
server.set('view engine', 'html');
23111
server.set('views', distFolder);
24112

25113
// Example Express Rest API endpoints
26114
// app.get('/api/**', (req, res) => { });
27115
// Serve static files from /browser
28-
server.get('*.*', express.static(distFolder, {
29-
maxAge: '1y'
30-
}));
116+
server.get(
117+
'*.*',
118+
express.static(distFolder, {
119+
maxAge: '1y',
120+
}),
121+
);
31122

32123
// All regular routes use the Universal engine
33124
server.get('*', (req, res) => {
34-
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
125+
global['navigator'] = req['headers']['user-agent'];
126+
const http =
127+
req.headers['x-forwarded-proto'] === undefined ? 'http' : req.headers['x-forwarded-proto'];
128+
129+
res.render(indexHtml, {
130+
req,
131+
providers: [
132+
{ provide: APP_BASE_HREF, useValue: req.baseUrl },
133+
134+
// for http and cookies
135+
{
136+
provide: REQUEST,
137+
useValue: req,
138+
},
139+
{
140+
provide: RESPONSE,
141+
useValue: res,
142+
},
143+
/// for cookie
144+
{
145+
provide: NgxRequest,
146+
useValue: req,
147+
},
148+
{
149+
provide: NgxResponse,
150+
useValue: res,
151+
},
152+
// for absolute path
153+
{
154+
provide: 'ORIGIN_URL',
155+
useValue: `${http}://${req.headers.host}`,
156+
},
157+
],
158+
});
35159
});
36160

37161
return server;
@@ -42,6 +166,11 @@ function run() {
42166

43167
// Start up the Node server
44168
const server = app();
169+
// gzip
170+
server.use(compression());
171+
// cokies
172+
server.use(cookieparser());
173+
45174
server.listen(port, () => {
46175
console.log(`Node Express server listening on http://localhost:${port}`);
47176
});
@@ -52,7 +181,7 @@ function run() {
52181
// The below code is to ensure that the server is run only when not requiring the bundle.
53182
declare const __non_webpack_require__: NodeRequire;
54183
const mainModule = __non_webpack_require__.main;
55-
const moduleFilename = mainModule && mainModule.filename || '';
184+
const moduleFilename = (mainModule && mainModule.filename) || '';
56185
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
57186
run();
58187
}

src/tsconfig.server.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
},
1313
"files": [
1414
"main.server.ts",
15-
"server.ts"
15+
"../server.ts"
1616
]
1717
}

0 commit comments

Comments
 (0)