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
function ngApp(req, res) {
80
  res.render('index', {
81
    req,
82
    res,
83
    // time: true, // use this to determine what part of your app is slow only in development
84
    preboot: false,
85
    baseUrl: '/',
86
    requestUrl: req.originalUrl,
87
    originUrl: `http://localhost:${ app.get('port') }`
88
  });
89
}
90

    
91
/**
92
 * use universal for specific routes
93
 */
94
app.get('/', ngApp);
95
routes.forEach(route => {
96
  app.get(`/${route}`, ngApp);
97
  app.get(`/${route}/*`, ngApp);
98
});
99

    
100

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

    
108
// Server
109
let server = app.listen(app.get('port'), () => {
110
  console.log(`Listening on: http://localhost:${server.address().port}`);
111
});
(9-9/12)