UNPKG

6.86 kBJavaScriptView Raw
1//
2// Module dependencies
3//
4var fs = require('fs'),
5 path = require('path'),
6 connect = require('connect'),
7 express = require('express'),
8 engines = require('consolidate'),
9 i18n = require('i18next'),
10 urljoin = require('./lib/urljoin'),
11 _ = require('lodash'),
12 logger = require('./lib/logger'),
13 settings = require('./config/settings');
14
15// Auto-load bundled middleware
16var middleware = {};
17
18fs.readdirSync(__dirname + '/lib/middleware').forEach(function(filename) {
19 if ( ! /\.js$/.test(filename)) {
20 return;
21 }
22 var name = path.basename(filename, '.js');
23 middleware[name] = require('./lib/middleware/' + name);
24});
25
26module.exports = function(options) {
27 options = options || {};
28
29 // Change route settings in multihost environment
30 settings.route = options.route || settings.route;
31
32 // Main app
33 var app = express();
34 var errorhandler = require('errorhandler');
35 var favicon = require('serve-favicon');
36 var cookieParser = require('cookie-parser');
37 var bodyParser = require('body-parser');
38 //var busboy = require('connect-busboy');
39 var multiparty = require('connect-multiparty');
40 var methodOverride = require('method-override');
41 var morgan = require('morgan');
42 var compress = require('compression');
43 var serveStatic = require('serve-static');
44
45 // Setup logger (winston)
46 logger.init(settings.winston);
47 logger.registerAppHelper(app); // Register app.locals (app.helper)
48
49 var log = logger();
50
51 // Setup i18n (i18next)
52 i18n.init(settings.i18next);
53 i18n.registerAppHelper(app); // Register app.locals (app.helper)
54
55 // Settings
56 (function(app) {
57 var env = process.env.NODE_ENV || 'development';
58 if ('development' === env) {
59 // Error handler - https://github.com/expressjs/errorhandler
60 // Development error handler, providing stack traces and error message responses
61 // for requests accepting text, html, or json.
62 app.use(errorhandler());
63
64 // a custom "verbose errors" setting which can be used in the templates via settings['verbose errors']
65 app.enable('verbose errors'); // Enables verbose errors in development
66 app.disable('view cache'); // Disables view template compilation caching in development
67 } else {
68 // a custom "verbose errors" setting which can be used in the templates via settings['verbose errors']
69 app.disable('verbose errors'); // Disables verbose errors in production
70 app.enable('view cache'); // Enables view template compilation caching in production
71 }
72
73 app.enable('trust proxy'); // Enables reverse proxy support, disabled by default
74 app.enable('case sensitive routing'); // Enable case sensitivity, disabled by default, treating "/Foo" and "/foo" as the same
75 app.disable('strict routing'); // Enable strict routing, by default "/foo" and "/foo/" are treated the same by the router
76 app.disable('x-powered-by'); // Enables the X-Powered-By: Express HTTP header, enabled by default
77
78 for (var i = 0; i < settings.view.engines.length; ++i) {
79 var extension = settings.view.engines[i].extension;
80 var template = settings.view.engines[i].template;
81 app.engine(extension, engines[template]);
82 }
83 app.set('view engine', settings.view.defaultExtension); // The default engine extension to use when omitted
84 app.set('views', path.join(__dirname, 'views')); // The view directory path
85
86 log.info('app.settings: %j', app.settings);
87 }(app));
88
89 // Removes the 'X-Powered-By' header in earlier versions of Express
90 app.use(function (req, res, next) {
91 res.removeHeader('X-Powered-By');
92 next();
93 });
94
95 // Cross-origin resource sharing
96 //app.use(middleware.cors());
97
98 // Middleware
99 // https://github.com/senchalabs/connect
100 app.use(favicon(path.join(__dirname, '../web/favicon.ico')));
101 app.use(cookieParser());
102
103 // Connect's body parsing middleware. This only handles urlencoded and json bodies.
104 // https://github.com/expressjs/body-parser
105 app.use(bodyParser.json(settings.middleware['body-parser']['json']));
106 app.use(bodyParser.urlencoded(settings.middleware['body-parser']['urlencoded']));
107
108 // For multipart bodies, please use the following modules:
109 // - [busboy](https://github.com/mscdex/busboy) and [connect-busboy](https://github.com/mscdex/connect-busboy)
110 // - [multiparty](https://github.com/andrewrk/node-multiparty) and [connect-multiparty](https://github.com/andrewrk/connect-multiparty)
111 app.use(multiparty(settings.middleware['multiparty']));
112
113 // https://github.com/dominictarr/connect-restreamer
114 // connect's bodyParser has a problem when using it with a proxy.
115 // It gobbles up all the body events, so that the proxy doesn't see anything!
116 app.use(require('connect-restreamer')());
117
118 app.use(methodOverride());
119 app.use(morgan(settings.middleware['morgan']));
120 app.use(compress(settings.middleware['compression']));
121
122 _.each(settings.assets, function(asset, name) {
123 log.info('assets: name=%s, asset=%s', name, JSON.stringify(asset));
124
125 if ( ! asset.path) {
126 log.error('asset path is not defined');
127 return;
128 }
129
130 _.each(asset.routes, function(asset_route) {
131 var route = urljoin(settings.route || '/', asset_route || '');
132 log.info('> route=%s', name, route);
133 app.use(route, serveStatic(asset.path, {
134 maxAge: asset.maxAge
135 }));
136 });
137 });
138
139 // i18n routing
140 app.use(i18n.handle);
141
142 // https://github.com/visionmedia/express/wiki/New-features-in-4.x
143 // No more app.use(app.router)
144 // All routing methods will be added in the order in which they appear. You should not do app.use(app.router). This eliminates the most common issue with Express.
145 var routes = require('./routes/main');
146 routes.init(app);
147
148 // Error handling
149 console.assert( ! _.isUndefined(middleware.err_log), 'lib/middleware/err_log not found');
150 console.assert( ! _.isUndefined(middleware.err_client), 'lib/middleware/err_client not found');
151 console.assert( ! _.isUndefined(middleware.err_notfound), 'lib/middleware/err_notfound not found');
152 console.assert( ! _.isUndefined(middleware.err_server), 'lib/middleware/err_server not found');
153
154 app.use(middleware.err_log());
155 app.use(middleware.err_client({
156 error: 'XHR error'
157 }));
158 app.use(middleware.err_notfound({
159 view: path.join('common', '404.hogan'),
160 error: 'Not found'
161 }));
162 app.use(middleware.err_server({
163 view: path.join('common', '500.jade'),
164 error: 'Internal server error'
165 }));
166
167 return app;
168};