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
import * as compression from 'compression';
16

    
17
// Angular 2
18
import { enableProdMode } from '@angular/core';
19
// Angular 2 Universal
20
import { createEngine } from 'angular2-express-engine';
21

    
22
// App
23
import { MainModuleNgFactory } from './node.module.ngfactory';
24

    
25
// Routes
26
import { routes } from './server.routes';
27

    
28
// enable prod for faster renders
29
enableProdMode();
30

    
31
const app = express();
32
const ROOT = path.join(path.resolve(__dirname, '..'));
33

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

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

    
50
app.use(cookieParser('Angular 2 Universal'));
51
app.use(bodyParser.json());
52
app.use(compression());
53

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

    
56
app.use(morgan('common', {
57
  skip: (req, res) => res.statusCode < 400,
58
  stream: accessLogStream
59
}));
60

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

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

    
79
process.on('uncaughtException', function (err) { 
80
  console.error('Catching uncaught errors to avoid process crash', err);
81
});
82

    
83
function ngApp(req, res) {
84

    
85
  function onHandleError(parentZoneDelegate, currentZone, targetZone, error)  {
86
    console.warn('Error in SSR, serving for direct CSR');
87
    res.sendFile('index.html', {root: './src'});
88
    return false;
89
  }
90

    
91
  Zone.current.fork({ name: 'CSR fallback', onHandleError }).run(() => {
92
    res.render('index', {
93
      req,
94
      res,
95
      // time: true, // use this to determine what part of your app is slow only in development
96
      preboot: false,
97
      baseUrl: '/',
98
      requestUrl: req.originalUrl,
99
      originUrl: `http://localhost:${ app.get('port') }`
100
    });
101
  });
102

    
103
}
104

    
105
/**
106
 * use universal for specific routes
107
 */
108
app.get('/', ngApp);
109
routes.forEach(route => {
110
  app.get(`/${route}`, ngApp);
111
  app.get(`/${route}/*`, ngApp);
112
});
113

    
114

    
115
app.get('*', function(req, res) {
116
  res.setHeader('Content-Type', 'application/json');
117
  var pojo = { status: 404, message: 'No Content' };
118
  var json = JSON.stringify(pojo, null, 2);
119
  res.status(404).send(json);
120
});
121

    
122
// Server
123
let server = app.listen(app.get('port'), () => {
124
  console.log(`Listening on: http://localhost:${server.address().port}`);
125
});
(9-9/12)