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 path from 'path';
10
import * as express from 'express';
11
import * as bodyParser from 'body-parser';
12
import * as cookieParser from 'cookie-parser';
13
import * as morgan from 'morgan';
14
import * as compression from 'compression';
15

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

    
21
// App
22
import { MainModule } from './node.module';
23

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

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

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

    
33
// Express View
34
app.engine('.html', createEngine({
35
  ngModule: MainModule,
36
  providers: [
37
    // use only if you have shared state between users
38
    // { provide: 'LRU', useFactory: () => new LRU(10) }
39

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

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

    
52
app.use(morgan('dev'));
53

    
54
function cacheControl(req, res, next) {
55
  // instruct browser to revalidate in 60 seconds
56
  res.header('Cache-Control', 'max-age=60');
57
  next();
58
}
59
// Serve static files
60
app.use('/assets', cacheControl, express.static(path.join(__dirname, 'assets'), {maxAge: 30}));
61
app.use(cacheControl, express.static(path.join(ROOT, 'dist/client'), {index: false}));
62

    
63
//
64
/////////////////////////
65
// ** Example API
66
// Notice API should be in aseparate process
67
import { serverApi, createTodoApi } from './backend/api';
68
// Our API for demos only
69
app.get('/data.json', serverApi);
70
app.use('/api', createTodoApi());
71

    
72
process.on('uncaughtException', function (err) { 
73
  console.error('Catching uncaught errors to avoid process crash', err);
74
});
75

    
76
function ngApp(req, res) {
77

    
78
  function onHandleError(parentZoneDelegate, currentZone, targetZone, error)  {
79
    console.warn('Error in SSR, serving for direct CSR');
80
    res.sendFile('index.html', {root: './src'});
81
    return false;
82
  }
83

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

    
96
}
97

    
98
/**
99
 * use universal for specific routes
100
 */
101
app.get('/', ngApp);
102
routes.forEach(route => {
103
  app.get(`/${route}`, ngApp);
104
  app.get(`/${route}/*`, ngApp);
105
});
106
app.get('*', ngApp);
107
/*app.get('*', function(req, res) {
108
  res.setHeader('Content-Type', 'application/json');
109
  var pojo = { status: 404, message: 'No Content' };
110
  var json = JSON.stringify(pojo, null, 2);
111
  res.status(404).send(json);
112
});
113
*/
114
// Server
115
let server = app.listen(app.get('port'), () => {
116
  console.log(`Listening on: http://localhost:${server.address().port}`);
117
});
(11-11/12)