UNPKG

react-middleware

Version:

Connect middleware for serving React components from a standard folder structure.

238 lines (192 loc) 8.43 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _ramda = require('ramda'); var _ramda2 = _interopRequireDefault(_ramda); var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk); var _express = require('express'); var _express2 = _interopRequireDefault(_express); var _compression = require('compression'); var _compression2 = _interopRequireDefault(_compression); var _fileSystemCss = require('file-system-css'); var _fileSystemCss2 = _interopRequireDefault(_fileSystemCss); var _filesize = require('filesize'); var _filesize2 = _interopRequireDefault(_filesize); var _paths = require('./paths'); var _paths2 = _interopRequireDefault(_paths); var _routerCss = require('./router-css'); var _routerCss2 = _interopRequireDefault(_routerCss); var _routerHtml = require('./router-html'); var _routerHtml2 = _interopRequireDefault(_routerHtml); var _routerJs = require('./router-js'); var _routerJs2 = _interopRequireDefault(_routerJs); var _webpackBuilder = require('./webpack-builder'); var _webpackBuilder2 = _interopRequireDefault(_webpackBuilder); var _templates = require('./templates'); var _templates2 = _interopRequireDefault(_templates); var _log = require('./log'); var _log2 = _interopRequireDefault(_log); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var IS_PRODUCTION = process.env.NODE_ENV === 'production'; /* eslint max-len:0 new-cap:0 */ var buildFunction = function buildFunction(middleware, paths, routes, loaders) { var builtResponse = void 0; return function () { var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; return new Promise(function (resolve, reject) { if (builtResponse && options.force !== true) { // Don't rebuild if compilation has already occured. resolve(builtResponse); } else { (0, _webpackBuilder2.default)({ paths: paths, routes: routes, loaders: loaders }).then(function (result) { builtResponse = result; resolve(result); }).catch(function (err) { // Failed to build. if (err.errors) { _log2.default.error(_chalk2.default.red('FAILED to compile javascript.\n')); err.errors.forEach(function (error) { return _log2.default.error(error.message); }); } reject(err); }); } }); }; }; /** * Returns the server middleware. * * @param options: * - base: The relative or absolute path to the base for all other relative paths. * - css: The relative or absolute path to the global CSS folder. * - public: The relative or absolute path to the public assets folder. * - layouts: The relative or absolute path to the page layouts folder. * - components: The relative or absolute path to the shared components folder. * - pages: The relative or absolute path to the pages folder. * - data: An {Object} or {Function} to pass as the root data object to the React page(s). * If a function is passed, details about the URL and rendering page are passed * as an argument. * This is useful as an API hook when creating a `react-middleware` package * to be shared as a module. * - watch: Flag indicating if changes to files should invalidate the cache. * True by default when not in 'production'. * - webpackLoaders: An array of webpack loaders to use. * Default loaders are replaced with this array. * - logger: Custom logger to use (object that exposes [info, warn, error] methods). * */ var api = function api() { var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; // Setup initial conditions. var watch = _ramda2.default.is(Boolean, options.watch) ? options.watch : !IS_PRODUCTION; // Prepare the middleware. var middleware = _express2.default.Router(); var paths = middleware.paths = (0, _paths2.default)(options); var templates = middleware.templates = (0, _templates2.default)(middleware.paths); var routes = templates.routes.import(); middleware.use((0, _compression2.default)()); middleware.use(_express2.default.static(paths.public, { maxage: '60 days' })); (0, _routerHtml2.default)(middleware, paths, routes, options.data); (0, _routerCss2.default)(middleware, paths, { watch: watch }); (0, _routerJs2.default)(middleware, routes); // Decorate the middleware with functions. middleware.start = function (startOptions) { return api.start((0, _express2.default)(), middleware, startOptions); }; middleware.clearCache = function () { return api.clearCache(); }; middleware.build = buildFunction(middleware, paths, routes, options.webpackLoaders); middleware.logger = options.logger || _log2.default; // Finish up. return middleware; }; /** * Starts a web server. * @param {function} app: The express instance (eg. app = express();) * If not specified a new express instance is created. * @param {function} middleware: The react-middleware instance to use. * @param {options} * - port: The port to run on. * - name: The display name of the server (emitted to the console). * - version: The version of the app (emitted to the console). * - silent: Flag indicating if startup output should be suppressed. * @return Promise. */ api.start = function (app, middleware) { var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; // Ensure required parameters were passed. if (!_ramda2.default.is(Function, app)) { throw new Error('Start Method: An express instance must be specified.'); } if (!_ramda2.default.is(Function, middleware)) { throw new Error('Start Method: The [react-middleware] instance must be specified.'); } // Extract startup values. if (_ramda2.default.is(Number, options)) { options = { port: options }; } var PORT = options.port || (IS_PRODUCTION ? 80 : 3030); var NAME = options.name || 'Server'; var SILENT = options.silent === undefined ? false : options.silent; var VERSION = options.version; var logger = middleware.logger; var logStarted = function logStarted(js) { logger.info(''); logger.info(_chalk2.default.green('Started: ' + NAME)); if (VERSION) { logger.info(_chalk2.default.grey(' - version:'), VERSION); } logger.info(_chalk2.default.grey(' - port: '), PORT); logger.info(_chalk2.default.grey(' - env: '), process.env.NODE_ENV || 'development'); if (js.files.length > 0) { var seconds = js.elapsed / 1000; logger.info(_chalk2.default.grey(' - js: '), Math.round(seconds * 10) / 10 + ' second build time'); js.files.forEach(function (item) { logger.info(_chalk2.default.grey(' - ' + item.path + ','), (0, _filesize2.default)(item.fileSize)); }); } logger.info(''); }; return new Promise(function (resolve, reject) { // Build the javascript (webpack). logger.info(_chalk2.default.grey('Starting \'' + NAME + '\'...')); middleware.build().then(function (js) { // Configure and start the express server. app.use(middleware).listen(PORT, function () { if (!SILENT) { logStarted(js); } resolve(); }); }).catch(function (err) { logger.error('err', err); reject(err); }); }); }; /** * Initalizes the default folder/template structure. * @param {string} path: The base-path. Use './' to create * relative to the root of the host module. */ api.init = function (path) { if (!_ramda2.default.is(String, path)) { path = './site'; } api({ base: path }).templates.createSync(); return api; }; /** * Clears all cached content. */ api.clearCache = function () { _fileSystemCss2.default.delete(); return api; }; // ---------------------------------------------------------------------------- exports.default = api; //# sourceMappingURL=middleware.js.map