Project

General

Profile

1
// the polyfills must be one of the first things imported in node.js.
2
// The only modules to be imported higher - node modules with es6-promise 3.x or other Promise polyfill dependency
3
// (rule of thumb: do it if you have zone.js exception that it has been overwritten)
4
// if you are including modules that modify Promise, such as NewRelic,, you must include them before polyfills
5
import 'angular2-universal-polyfills';
6
import 'ts-helpers';
7
import './__workaround.node'; // temporary until 2.1.1 things are patched in Core
8

    
9
import * as fs from 'fs';
10
import * as path from 'path';
11
import * as express from 'express';
12
import * as bodyParser from 'body-parser';
13
import * as cookieParser from 'cookie-parser';
14
import * as morgan from 'morgan';
15

    
16
const { gzipSync } = require('zlib');
17
const accepts = require('accepts');
18
const { compressSync } = require('iltorb');
19
const interceptor = require('express-interceptor');
20

    
21
// Angular 2
22
import { enableProdMode } from '@angular/core';
23
// Angular 2 Universal
24
import { createEngine } from 'angular2-express-engine';
25

    
26
// App
27
import { MainModuleNgFactory } from './node.module.ngfactory';
28

    
29
// Routes
30
import { routes } from './server.routes';
31

    
32
// enable prod for faster renders
33
enableProdMode();
34

    
35
const app = express();
36
const ROOT = path.join(path.resolve(__dirname, '..'));
37

    
38
// Express View
39
app.engine('.html', createEngine({
40
  precompile: false, // this needs to be false when using ngFactory
41
  ngModule: MainModuleNgFactory,
42
  providers: [
43
    // use only if you have shared state between users
44
    // { provide: 'LRU', useFactory: () => new LRU(10) }
45

    
46
    // stateless providers only since it's shared
47
  ]
48
}));
49
app.set('port', process.env.PORT || 3000);
50
app.set('views', __dirname);
51
app.set('view engine', 'html');
52
app.set('json spaces', 2);
53

    
54
app.use(cookieParser('Angular 2 Universal'));
55
app.use(bodyParser.json());
56
app.use(compression());
57

    
58
const accessLogStream = fs.createWriteStream(ROOT + '/morgan.log', {flags: 'a'})
59

    
60
app.use(morgan('common', {
61
  skip: (req, res) => res.statusCode < 400,
62
  stream: accessLogStream
63
}));
64

    
65
function cacheControl(req, res, next) {
66
  // instruct browser to revalidate in 60 seconds
67
  res.header('Cache-Control', 'max-age=60');
68
  next();
69
}
70
// Serve static files
71
app.use('/assets', cacheControl, express.static(path.join(__dirname, 'assets'), {maxAge: 30}));
72
app.use(cacheControl, express.static(path.join(ROOT, 'dist/client'), {index: false}));
73

    
74
//
75
/////////////////////////
76
// ** Example API
77
// Notice API should be in aseparate process
78
import { serverApi, createTodoApi } from './backend/api';
79
// Our API for demos only
80
app.get('/data.json', serverApi);
81
app.use('/api', createTodoApi());
82

    
83
function ngApp(req, res) {
84
  res.render('index', {
85
    req,
86
    res,
87
    // time: true, // use this to determine what part of your app is slow only in development
88
    preboot: false,
89
    baseUrl: '/',
90
    requestUrl: req.originalUrl,
91
    originUrl: `http://localhost:${ app.get('port') }`
92
  });
93
}
94

    
95
/**
96
 * use universal for specific routes
97
 */
98
app.get('/', ngApp);
99
routes.forEach(route => {
100
  app.get(`/${route}`, ngApp);
101
  app.get(`/${route}/*`, ngApp);
102
});
103

    
104

    
105
app.get('*', function(req, res) {
106
  res.setHeader('Content-Type', 'application/json');
107
  var pojo = { status: 404, message: 'No Content' };
108
  var json = JSON.stringify(pojo, null, 2);
109
  res.status(404).send(json);
110
});
111

    
112
// Server
113
let server = app.listen(app.get('port'), () => {
114
  console.log(`Listening on: http://localhost:${server.address().port}`);
115
});
(9-9/12)