webappengine
Version:
A web application server that can host multiple web apps running with Node.js.
333 lines (235 loc) • 11.7 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _path2 = require('path');
var _path3 = _interopRequireDefault(_path2);
var _express = require('express');
var _express2 = _interopRequireDefault(_express);
var _consolidate = require('consolidate');
var _consolidate2 = _interopRequireDefault(_consolidate);
var _errorhandler = require('errorhandler');
var _errorhandler2 = _interopRequireDefault(_errorhandler);
var _serveFavicon = require('serve-favicon');
var _serveFavicon2 = _interopRequireDefault(_serveFavicon);
var _cookieParser = require('cookie-parser');
var _cookieParser2 = _interopRequireDefault(_cookieParser);
var _bodyParser = require('body-parser');
var _bodyParser2 = _interopRequireDefault(_bodyParser);
var _connectMultiparty = require('connect-multiparty');
var _connectMultiparty2 = _interopRequireDefault(_connectMultiparty);
var _connectRestreamer = require('connect-restreamer');
var _connectRestreamer2 = _interopRequireDefault(_connectRestreamer);
var _methodOverride = require('method-override');
var _methodOverride2 = _interopRequireDefault(_methodOverride);
var _morgan = require('morgan');
var _morgan2 = _interopRequireDefault(_morgan);
var _compression = require('compression');
var _compression2 = _interopRequireDefault(_compression);
var _serveStatic = require('serve-static');
var _serveStatic2 = _interopRequireDefault(_serveStatic);
var _expressSession = require('express-session');
var _expressSession2 = _interopRequireDefault(_expressSession);
var _sessionFileStore = require('session-file-store');
var _sessionFileStore2 = _interopRequireDefault(_sessionFileStore);
var _i18next = require('i18next');
var _i18next2 = _interopRequireDefault(_i18next);
var _i18nextNodeFsBackend = require('i18next-node-fs-backend');
var _i18nextNodeFsBackend2 = _interopRequireDefault(_i18nextNodeFsBackend);
var _del = require('del');
var _del2 = _interopRequireDefault(_del);
var _i18nextExpressMiddleware = require('i18next-express-middleware');
var _urljoin = require('./lib/urljoin');
var _urljoin2 = _interopRequireDefault(_urljoin);
var _log = require('./lib/log');
var _log2 = _interopRequireDefault(_log);
var _settings = require('./config/settings');
var _settings2 = _interopRequireDefault(_settings);
var _errclient = require('./lib/middleware/errclient');
var _errclient2 = _interopRequireDefault(_errclient);
var _errlog = require('./lib/middleware/errlog');
var _errlog2 = _interopRequireDefault(_errlog);
var _errnotfound = require('./lib/middleware/errnotfound');
var _errnotfound2 = _interopRequireDefault(_errnotfound);
var _errserver = require('./lib/middleware/errserver');
var _errserver2 = _interopRequireDefault(_errserver);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var renderPage = function renderPage(req, res, next) {
var view = req.params[0] || 'index';
var file = view + '.hbs';
if (_fs2.default.existsSync(_path3.default.resolve(__dirname, 'views', file))) {
var cdn = void 0,
webroot = void 0,
version = void 0;
// cdn
if (_lodash2.default.isEmpty(_settings2.default.cdn.uri)) {
cdn = (0, _urljoin2.default)(_settings2.default.assets.web.routes[0], '/'); // with trailing slash
} else {
cdn = (0, _urljoin2.default)(_settings2.default.cdn.uri, _settings2.default.assets.web.routes[0], '/'); // with trailing slash
}
// webroot
webroot = (0, _urljoin2.default)(_settings2.default.assets.web.routes[0], '/'); // with trailing slash
// version
version = _settings2.default.version;
var lng = req.language;
var t = req.t;
// Override IE's Compatibility View Settings
// http://stackoverflow.com/questions/6156639/x-ua-compatible-is-set-to-ie-edge-but-it-still-doesnt-stop-compatibility-mode
res.set({ 'X-UA-Compatible': 'IE=edge' });
res.render(file, {
'cdn': cdn,
'webroot': webroot,
'version': version,
'lang': lng,
'title': t('title'),
'dir': t('config:dir')
});
return;
}
next();
};
var webpackMain = function webpackMain(app) {
if (process.env.NODE_ENV !== 'development') {
_log2.default.error('The process.env.NODE_ENV should be "development" while running a webpack server');
return;
}
var webpack = require('webpack');
var config = require('../../webpack.config.development');
var compiler = webpack(config);
// https://github.com/webpack/webpack-dev-middleware
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: false,
quite: false,
lazy: false,
// https://webpack.github.io/docs/node.js-api.html#compiler
watchOptions: {
poll: true // use polling instead of native watchers
},
publicPath: config.output.publicPath,
stats: {
colors: true
}
}));
app.use(require('webpack-hot-middleware')(compiler));
};
var appMain = function appMain() {
var app = (0, _express2.default)();
{
// Settings
if (_settings2.default.env === 'development') {
webpackMain(app);
// Error handler - https://github.com/expressjs/errorhandler
// Development error handler, providing stack traces and error message responses
// for requests accepting text, html, or json.
app.use((0, _errorhandler2.default)());
// a custom "verbose errors" setting which can be used in the templates via settings['verbose errors']
app.enable('verbose errors'); // Enables verbose errors in development
app.disable('view cache'); // Disables view template compilation caching in development
} else {
// a custom "verbose errors" setting which can be used in the templates via settings['verbose errors']
app.disable('verbose errors'); // Disables verbose errors in production
app.enable('view cache'); // Enables view template compilation caching in production
}
app.enable('trust proxy'); // Enables reverse proxy support, disabled by default
app.enable('case sensitive routing'); // Enable case sensitivity, disabled by default, treating "/Foo" and "/foo" as the same
app.disable('strict routing'); // Enable strict routing, by default "/foo" and "/foo/" are treated the same by the router
app.disable('x-powered-by'); // Enables the X-Powered-By: Express HTTP header, enabled by default
for (var i = 0; i < _settings2.default.view.engines.length; ++i) {
var extension = _settings2.default.view.engines[i].extension;
var template = _settings2.default.view.engines[i].template;
app.engine(extension, _consolidate2.default[template]);
}
app.set('view engine', _settings2.default.view.defaultExtension); // The default engine extension to use when omitted
app.set('views', _path3.default.resolve(__dirname, 'views')); // The view directory path
_log2.default.debug('app.settings: %j', app.settings);
}
// Setup i18n (i18next)
_i18next2.default.use(_i18nextNodeFsBackend2.default).use(_i18nextExpressMiddleware.LanguageDetector).init(_settings2.default.i18next);
// Removes the 'X-Powered-By' header in earlier versions of Express
app.use(function (req, res, next) {
res.removeHeader('X-Powered-By');
next();
});
// Middleware
// https://github.com/senchalabs/connect
{
// https://github.com/valery-barysok/session-file-store
var _path = './sessions';
_del2.default.sync([_path]);
_fs2.default.mkdirSync(_path); // Defaults to ./sessions
app.use((0, _expressSession2.default)(_lodash2.default.merge({}, _settings2.default.middleware.session, {
store: new ((0, _sessionFileStore2.default)(_expressSession2.default))({
path: _path,
logFn: function logFn() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_log2.default.debug.apply(_log2.default, args);
}
})
})));
}
app.use((0, _serveFavicon2.default)(_path3.default.join(_settings2.default.assets.web.path, 'favicon.ico')));
app.use((0, _cookieParser2.default)());
// Connect's body parsing middleware. This only handles urlencoded and json bodies.
// https://github.com/expressjs/body-parser
app.use(_bodyParser2.default.json(_settings2.default.middleware['body-parser'].json));
app.use(_bodyParser2.default.urlencoded(_settings2.default.middleware['body-parser'].urlencoded));
// For multipart bodies, please use the following modules:
// - [busboy](https://github.com/mscdex/busboy) and [connect-busboy](https://github.com/mscdex/connect-busboy)
// - [multiparty](https://github.com/andrewrk/node-multiparty) and [connect-multiparty](https://github.com/andrewrk/connect-multiparty)
app.use((0, _connectMultiparty2.default)(_settings2.default.middleware.multiparty));
// https://github.com/dominictarr/connect-restreamer
// connect's bodyParser has a problem when using it with a proxy.
// It gobbles up all the body events, so that the proxy doesn't see anything!
app.use((0, _connectRestreamer2.default)());
// https://github.com/expressjs/method-override
app.use((0, _methodOverride2.default)());
if (_settings2.default.verbosity > 0) {
// https://github.com/expressjs/morgan#use-custom-token-formats
// Add an ID to all requests and displays it using the :id token
_morgan2.default.token('id', function (req, res) {
return req.session.id;
});
app.use((0, _morgan2.default)(_settings2.default.middleware.morgan.format));
}
app.use((0, _compression2.default)(_settings2.default.middleware.compression));
_lodash2.default.each(_settings2.default.assets, function (asset, name) {
_log2.default.debug('assets: name=%s, asset=%s', name, JSON.stringify(asset));
if (!asset.path) {
_log2.default.error('asset path is not defined');
return;
}
_lodash2.default.each(asset.routes, function (assetRoute) {
var route = (0, _urljoin2.default)(_settings2.default.route || '/', assetRoute || '');
_log2.default.debug('> route=%s', name, route);
app.use(route, (0, _serveStatic2.default)(asset.path, {
maxAge: asset.maxAge
}));
});
});
app.use((0, _i18nextExpressMiddleware.handle)(_i18next2.default, {}));
// page
app.get((0, _urljoin2.default)(_settings2.default.route, '*'), renderPage);
{
// Error handling
app.use((0, _errlog2.default)());
app.use((0, _errclient2.default)({
error: 'XHR error'
}));
app.use((0, _errnotfound2.default)({
view: _path3.default.join('common', '404.hogan'),
error: 'Not found'
}));
app.use((0, _errserver2.default)({
view: _path3.default.join('common', '500.hogan'),
error: 'Internal server error'
}));
}
return app;
};
exports.default = appMain;