germ
Version:
Opinionated boilerplate to unify server and client side code
179 lines (144 loc) • 10.8 kB
JavaScript
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
var react = __webpack_require__(1)
, route = __webpack_require__(2)
, indexApp = __webpack_require__(3);
var routeState;
/*
* [RUN-IN-CLIENT]
* Bootstrap the client environment to use the HTML5 history push/pop states
* for routing and expose our globe initial state.
*/
if(true) {
// wire up the HTML5 history to our routes and on change
window.History.Adapter.bind(window, "statechange", function() {
routeState = route(document.location.pathname + document.location.search);
react.renderComponent(routeState.view(routeState.props), document.getElementById('viewport'));
});
/*
* [RUN-IN-SERVER]
* Bootstrap the server environment to parse routes and handle a basic API call.
*/
} else if(process.env.RUN_ENV === 'server') {
module.exports = function(app, next) {
app.use(function(req,res,next) {
routeState = route(req.originalUrl);
// if no match let expressjs handle the request.
if(!routeState ) {
return next();
}
var html = react.renderComponentToString(routeState.view(routeState.props));
res.render('web-app', {viewport: html});
});
app.get('/api/ping', function(req, res, next) {
res.send('pong');
});
next(null);
}
}
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
module.exports = window.React;
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
var crossroads = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"crossroads\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()))
, webApp = __webpack_require__(4)
, indexView = __webpack_require__(3);
var routes = crossroads.create()
, routeState;
// [RUN-IN-SERVER] we need to always fire a route change.
// for example if two sequential request for /test & /test
// hit the routes we need to always fire a change but, for
// the [RUN-IN-CLIENT] we only want to fire when history url
// changes like /test to /home
if(false) {
routes.ignoreState = true;
}
routes.addRoute(/.*/, function(){
console.log('match')
routeState = {
view: indexView, //# you do not need a controller
//controller: webApp,
props: {
}
};
});
routes.bypassed.add(function() {
routeState = false;
});
/**
*
* @param url
* @returns a Ract component
*/
module.exports = function(url) {
routeState = null;
routes.parse(url);
if(routeState) {
routeState.url = url;
}
return routeState;
}
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
/** @jsx React.DOM */
var React = __webpack_require__(1);module.exports = React.createClass({displayName: 'exports',
render: function() {
return React.DOM.h1(null, "Hello World");
}
});
/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {
var indexView = __webpack_require__(3);
module.exports = function(routeState, req, res, next) {
}
/***/ }
/******/ ])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2svYm9vdHN0cmFwIDllZDQ3NjQ3ZWEyYmQ3MzFlYTgxIiwiLi9hcHAvd2ViLWJvb3RzdHJhcC5qcyIsImV4dGVybmFsIFwid2luZG93LlJlYWN0XCIiLCIuL2FwcC93ZWItcm91dGVzLmpzIiwiLi9jb21wb25lbnRzL2luZGV4LmpzIiwiLi9jb250cm9sbGVycy93ZWItYXBwLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHdDOzs7Ozs7O0FDdENBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7Ozs7Ozs7O0FBUUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOEJBQTZCLGVBQWU7QUFDNUMsTUFBSzs7QUFFTDtBQUNBO0FBQ0EsTUFBSzs7QUFFTDtBQUNBO0FBQ0EsRTs7Ozs7O0FDaERBLCtCOzs7Ozs7QUNBQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7QUM1Q0E7QUFDQSxvQ0FBNkIsb0NBQW9DO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBLEVBQUM7Ozs7Ozs7QUNMRDs7QUFFQTs7QUFFQSIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKVxuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuXG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRleHBvcnRzOiB7fSxcbiBcdFx0XHRpZDogbW9kdWxlSWQsXG4gXHRcdFx0bG9hZGVkOiBmYWxzZVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKDApOyIsInZhciByZWFjdCA9IHJlcXVpcmUoJ3JlYWN0JylcbiAgLCByb3V0ZSA9IHJlcXVpcmUoJy4vd2ViLXJvdXRlcycpXG4gICwgaW5kZXhBcHAgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL2luZGV4Jyk7XG5cbnZhciByb3V0ZVN0YXRlO1xuXG4vKlxuICogW1JVTi1JTi1DTElFTlRdXG4gKiBCb290c3RyYXAgdGhlIGNsaWVudCBlbnZpcm9ubWVudCB0byB1c2UgdGhlIEhUTUw1IGhpc3RvcnkgcHVzaC9wb3Agc3RhdGVzXG4gKiBmb3Igcm91dGluZyBhbmQgZXhwb3NlIG91ciBnbG9iZSBpbml0aWFsIHN0YXRlLlxuICovXG5pZihwcm9jZXNzLmVudi5SVU5fRU5WID09PSAnYnJvd3NlcicpIHtcbiAgLy8gd2lyZSB1cCB0aGUgSFRNTDUgaGlzdG9yeSB0byBvdXIgcm91dGVzIGFuZCBvbiBjaGFuZ2VcbiAgd2luZG93Lkhpc3RvcnkuQWRhcHRlci5iaW5kKHdpbmRvdywgXCJzdGF0ZWNoYW5nZVwiLCBmdW5jdGlvbigpIHtcbiAgICByb3V0ZVN0YXRlID0gcm91dGUoZG9jdW1lbnQubG9jYXRpb24ucGF0aG5hbWUgKyBkb2N1bWVudC5sb2NhdGlvbi5zZWFyY2gpO1xuICAgIHJlYWN0LnJlbmRlckNvbXBvbmVudChyb3V0ZVN0YXRlLnZpZXcocm91dGVTdGF0ZS5wcm9wcyksIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWV3cG9ydCcpKTtcbiAgfSk7XG5cblxuXG5cblxuXG5cbi8qXG4gKiBbUlVOLUlOLVNFUlZFUl1cbiAqIEJvb3RzdHJhcCB0aGUgc2VydmVyIGVudmlyb25tZW50IHRvIHBhcnNlIHJvdXRlcyBhbmQgaGFuZGxlIGEgYmFzaWMgQVBJIGNhbGwuXG4gKi9cbn0gZWxzZSBpZihwcm9jZXNzLmVudi5SVU5fRU5WID09PSAnc2VydmVyJykge1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGFwcCwgbmV4dCkge1xuICAgIGFwcC51c2UoZnVuY3Rpb24ocmVxLHJlcyxuZXh0KSB7XG4gICAgICByb3V0ZVN0YXRlID0gcm91dGUocmVxLm9yaWdpbmFsVXJsKTtcblxuICAgICAgLy8gaWYgbm8gbWF0Y2ggbGV0IGV4cHJlc3NqcyBoYW5kbGUgdGhlIHJlcXVlc3QuXG4gICAgICBpZighcm91dGVTdGF0ZSApIHtcbiAgICAgICAgcmV0dXJuIG5leHQoKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGh0bWwgPSByZWFjdC5yZW5kZXJDb21wb25lbnRUb1N0cmluZyhyb3V0ZVN0YXRlLnZpZXcocm91dGVTdGF0ZS5wcm9wcykpO1xuICAgICAgcmVzLnJlbmRlcignd2ViLWFwcCcsIHt2aWV3cG9ydDogaHRtbH0pO1xuICAgIH0pO1xuXG4gICAgYXBwLmdldCgnL2FwaS9waW5nJywgZnVuY3Rpb24ocmVxLCByZXMsIG5leHQpIHtcbiAgICAgIHJlcy5zZW5kKCdwb25nJyk7XG4gICAgfSk7XG5cbiAgICBuZXh0KG51bGwpO1xuICB9XG59IiwibW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cuUmVhY3Q7IiwidmFyIGNyb3Nzcm9hZHMgPSByZXF1aXJlKCdjcm9zc3JvYWRzJylcbiAgLCB3ZWJBcHAgPSByZXF1aXJlKCcuLi9jb250cm9sbGVycy93ZWItYXBwJylcbiAgLCBpbmRleFZpZXcgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL2luZGV4Jyk7XG5cbnZhciByb3V0ZXMgPSBjcm9zc3JvYWRzLmNyZWF0ZSgpXG4gICwgcm91dGVTdGF0ZTtcblxuLy8gW1JVTi1JTi1TRVJWRVJdIHdlIG5lZWQgdG8gYWx3YXlzIGZpcmUgYSByb3V0ZSBjaGFuZ2UuXG4vLyBmb3IgZXhhbXBsZSBpZiB0d28gc2VxdWVudGlhbCByZXF1ZXN0IGZvciAvdGVzdCAmIC90ZXN0XG4vLyBoaXQgdGhlIHJvdXRlcyB3ZSBuZWVkIHRvIGFsd2F5cyBmaXJlIGEgY2hhbmdlIGJ1dCwgZm9yXG4vLyB0aGUgW1JVTi1JTi1DTElFTlRdIHdlIG9ubHkgd2FudCB0byBmaXJlIHdoZW4gaGlzdG9yeSB1cmxcbi8vIGNoYW5nZXMgbGlrZSAvdGVzdCB0byAvaG9tZVxuaWYocHJvY2Vzcy5lbnYuUlVOX0VOViA9PT0gJ3NlcnZlcicpIHtcbiAgcm91dGVzLmlnbm9yZVN0YXRlID0gdHJ1ZTtcbn1cblxucm91dGVzLmFkZFJvdXRlKC8uKi8sIGZ1bmN0aW9uKCl7XG4gIGNvbnNvbGUubG9nKCdtYXRjaCcpXG4gIHJvdXRlU3RhdGUgPSB7XG4gICAgdmlldzogaW5kZXhWaWV3LCAvLyMgeW91IGRvIG5vdCBuZWVkIGEgY29udHJvbGxlclxuICAgIC8vY29udHJvbGxlcjogd2ViQXBwLFxuICAgIHByb3BzOiB7XG4gICAgfVxuICB9O1xufSk7XG5cbnJvdXRlcy5ieXBhc3NlZC5hZGQoZnVuY3Rpb24oKSB7XG4gIHJvdXRlU3RhdGUgPSBmYWxzZTtcbn0pO1xuXG4vKipcbiAqXG4gKiBAcGFyYW0gdXJsXG4gKiBAcmV0dXJucyBhIFJhY3QgY29tcG9uZW50XG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24odXJsKSB7XG4gIHJvdXRlU3RhdGUgPSBudWxsO1xuICByb3V0ZXMucGFyc2UodXJsKTtcblxuICBpZihyb3V0ZVN0YXRlKSB7XG4gICAgcm91dGVTdGF0ZS51cmwgPSB1cmw7XG4gIH1cblxuICByZXR1cm4gcm91dGVTdGF0ZTtcbn1cbiIsIi8qKiBAanN4IFJlYWN0LkRPTSAqL1xudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTttb2R1bGUuZXhwb3J0cyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogJ2V4cG9ydHMnLFxuICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBSZWFjdC5ET00uaDEobnVsbCwgXCJIZWxsbyBXb3JsZFwiKTtcbiAgfVxufSk7XG4iLCJ2YXIgaW5kZXhWaWV3ID0gcmVxdWlyZSgnLi4vY29tcG9uZW50cy9pbmRleCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHJvdXRlU3RhdGUsIHJlcSwgcmVzLCBuZXh0KSB7XG5cbn1cbiJdLCJzb3VyY2VSb290Ijoid2VicGFjay1tb2R1bGU6Ly8ifQ==