react-middleware
Version:
Connect middleware for serving React components from a standard folder structure.
224 lines (177 loc) • 7.78 kB
JavaScript
;
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 _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 _util = require("./util");
var util = _interopRequireWildcard(_util);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var IS_PRODUCTION = process.env.NODE_ENV === "production";
var buildFunction = function buildFunction(middleware, paths, routes) {
var builtResponse = undefined;
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, routes).then(function (result) {
builtResponse = result;
resolve(result);
}).catch(function (err) {
// Failed to build.
if (err.errors) {
console.error(_chalk2.default.red("FAILED to compile javascript.\n"));
err.errors.forEach(function (error) {
return console.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".
*/
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);
// 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).
* - 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 logStarted = function logStarted(js) {
console.log("");
console.log(_chalk2.default.green(NAME + ":"));
console.log(_chalk2.default.grey(" - port:"), PORT);
console.log(_chalk2.default.grey(" - env: "), process.env.NODE_ENV || "development");
if (js.files.length > 0) {
console.log(_chalk2.default.grey(" - js: "), (js.elapsed / 1000).toPrecision(1) + " second build time");
js.files.forEach(function (item) {
console.log(_chalk2.default.grey(" - " + item.path + ","), util.fileSize(item.fileSize));
});
}
console.log("");
};
return new Promise(function (resolve, reject) {
// Build the javascript (webpack).
console.log(_chalk2.default.grey("Starting..."));
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) {
console.log("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;