diff --git a/common/app/app-stream.jsx b/common/app/app-stream.jsx index 23506e4d5f..9c811f7457 100644 --- a/common/app/app-stream.jsx +++ b/common/app/app-stream.jsx @@ -1,24 +1,12 @@ import Rx from 'rx'; -import React from 'react'; -import { Route, Router } from 'react-router'; +import { Router } from 'react-router'; +import App from './App.jsx'; -// components -import { App } from './App.jsx'; -import { Jobs } from './routes/Jobs'; -import { NotFound } from './components/NotFound'; +import childRoutes from './routes'; const router$ = Rx.Observable.fromNodeCallback(Router.run, Router); -const routes = ( - - - - -); +const routes = Object.assign({ components: App }, childRoutes); export default function app$(location) { return router$(routes, location); diff --git a/common/app/routes/Jobs/index.js b/common/app/routes/Jobs/index.js index b18ca761d8..88bab9f6eb 100644 --- a/common/app/routes/Jobs/index.js +++ b/common/app/routes/Jobs/index.js @@ -1,3 +1,5 @@ +import Jobs from './components/Jobs.jsx'; + /* * show: /jobs * showOne: /jobs/:id @@ -8,12 +10,9 @@ export default { path: '/jobs/(:jobId)', - getComponents(cb) { - require.ensure([], require => { - cb(null, [ - require('./components/Jobs.jsx') - ]); - }); + setTimeout(() => { + cb(null, Jobs); + }, 0); } }; diff --git a/common/app/routes/Mobile/components/Mobile.jsx b/common/app/routes/Mobile/components/Mobile.jsx new file mode 100644 index 0000000000..88158ce8eb --- /dev/null +++ b/common/app/routes/Mobile/components/Mobile.jsx @@ -0,0 +1,18 @@ +import React, { PropTypes } from 'react'; + +export default React.createClass({ + displayName: 'Mobile', + propTypes: { + id: PropTypes.string + }, + + render() { + const { + id + } = this.props; + + return ( +

Hello { id }

+ ); + } +}); diff --git a/common/app/routes/Mobile/index.js b/common/app/routes/Mobile/index.js new file mode 100644 index 0000000000..41d32112f9 --- /dev/null +++ b/common/app/routes/Mobile/index.js @@ -0,0 +1,11 @@ +import Mobile from './components/Mobile.jsx'; + +export default { + path: 'mobile', + + getComponents(cb) { + setTimeout(() => { + cb(null, Mobile); + }, 0); + } +}; diff --git a/common/app/routes/index.js b/common/app/routes/index.js index 6e67b86742..88699d74d3 100644 --- a/common/app/routes/index.js +++ b/common/app/routes/index.js @@ -1,11 +1,15 @@ +import jobRoute from './Jobs'; +import mobileRoute from './Mobile'; + export default { path: '/', - getRoutes(cb) { - require.ensure([], require => { + getChildRoutes(locationState, cb) { + setTimeout(() => { cb(null, [ // require('./Bonfires'), - require('./Jobs') + jobRoute, + mobileRoute ]); - }); + }, 0); } }; diff --git a/gulpfile.js b/gulpfile.js index c858cc766d..43916c77e3 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,5 +1,6 @@ require('babel-core/register'); -var gulp = require('gulp'), +var Rx = require('rx'), + gulp = require('gulp'), path = require('path'), // utils @@ -30,6 +31,7 @@ var gulp = require('gulp'), eslint = require('gulp-eslint'); +Rx.longStackSupport = true; var reloadDelay = 1000; var reload = sync.reload; var paths = { @@ -105,6 +107,12 @@ gulp.task('pack-client', function() { .pipe(gulp.dest(webpackConfig.output.path)); }); +gulp.task('pack-watch', function() { + return gulp.src(webpackConfig.entry) + .pipe(webpack(Object.assign(webpackConfig, { watch: true }))) + .pipe(gulp.dest(webpackConfig.output.path)); +}); + gulp.task('pack-node', function() { return gulp.src(webpackConfigNode.entry) .pipe(webpack(webpackConfigNode)) @@ -175,7 +183,7 @@ gulp.task('watch', ['less', 'serve', 'sync'], function() { gulp.watch('./public/css/*.less', ['less']); }); -gulp.task('default', ['less', 'serve', 'sync', 'watch']); +gulp.task('default', ['less', 'serve', 'sync', 'watch', 'pack-watch']); function errorNotifier() { var args = Array.prototype.slice.call(arguments); diff --git a/package.json b/package.json index f146f83c3c..eba0961b60 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "ramda": "~0.10.0", "react": "^0.13.3", "react-bootstrap": "^0.23.5", - "react-router": "^1.0.0-beta1", + "react-router": "^1.0.0-beta3", "request": "~2.53.0", "rx": "^2.5.3", "sanitize-html": "~1.6.1", diff --git a/server/boot/a-react.js b/server/boot/a-react.js index 8af06696d4..6f00fd82f8 100644 --- a/server/boot/a-react.js +++ b/server/boot/a-react.js @@ -1,3 +1,6 @@ +import React from 'react'; +import Router from 'react-router'; +import Location from 'react-router/lib/Location'; import debugFactory from 'debug'; import { app$ } from '../../common/app'; import { Cat } from 'thundercats'; @@ -7,7 +10,7 @@ const debug = debugFactory('freecc:servereact'); // add routes here as they slowly get reactified // remove their individual controllers const routes = [ - '/jobs' + '/mobile' ]; export default function reactSubRouter(app) { @@ -20,13 +23,15 @@ export default function reactSubRouter(app) { app.use(router); function serveReactApp(req, res, next) { - var fcc = new Cat(); - var decodedUrl = decodeURI(req.path); + const fcc = new Cat(); + const location = new Location(req.path, req.query) // returns a router wrapped app - app$(decodedUrl) + app$(location) // if react-router does not find a route send down the chain - .filter(function(data) { + .filter(function(initialState) { + console.log('initialState', initialState); + /* var state = data.state; // this may not work with react-router 1.0.0 var notFound = state.routes.some(route => route.isNotFound); @@ -35,19 +40,23 @@ export default function reactSubRouter(app) { next(); } return !notFound; + */ + return true; }) - .flatMap(function(app) { + .flatMap(function(initialState) { // call thundercats renderToString // prefetches data and sets up it up for current state - return fcc.renderToString(app); + return fcc.renderToString( + React.createElement(Router, initialState[0]) + ); }) // makes sure we only get one onNext and closes subscription .firstOrDefault() - .flatMap(function(dats) { + .flatMap(function({ data, markup }) { debug('react rendered'); - res.expose(dats.data, 'data'); + res.expose(data, 'data'); // now render jade file with markup injected from react - return res.render$('layout-react', { markup: dats.markup }); + return res.render$('layout-react', { markup: markup }); }) .subscribe( function(markup) {