RENO is an example app that demonstrates how to set up a full stack React.js app. See it live at reno-demo.herokuapp.com.
Create a new directory and run the follwing command in your shell.
$ git clone git://github.com/SFDevLabs/reno.git
$ npm install
$ npm start
Then visit http://localhost:3000/. This starts the Express powered API and the Webpack-dev-server. Webpack will bundle the front end JSX/JS every time you make a file change in the "app/js" folder.
- React.js / Flux Front End (Look in the directory /app/js)
- CRUD API built in Express.js and MongoDB
- Webpack configuration
- Passport.js authentication
- CDN image upload via Imager
- Application emails via Notifier
- Lots of tests
##Why RENO? Because we need a good simple example of an end-to-end React app. Motivated by the javascript fatigue some new developers face.
When a user interacts wth RENO (i.e. creates a post) data flows through a series of steps. These steps mirror the folders structure located at app/js.
-
Components: The React classes and JSX that declare our UI elements
React.createClass({ ... _save: function() { Actions.create(this.state); } })
-
Actions: The central module for actions we register on our UI elements
... create: function(obj) { ArticleApi.postEntityData(obj); }
-
API: The XHR module where we make GET/POST/PUT/DELETE requests
... postEntityData: function(data) { ... const key = Constants.POST_ARTICLE_DATA; _pendingRequests[key] = RequestAPI.post(url, params).end( RequestAPI.makeResponseCallback(key, params) ); }
-
Dispatch: The Flux dipatcher that fires the callback when we call the dispatcher's dispatch methode
makeResponseCallback: function(){ ... dispatch(key, res, params); } ... function dispatch(key, response, params, data) { var payload = {actionType: key, response: response}; if (params) { payload.params = params; } if (data) { payload.data = data; } AppDispatcher.dispatch(payload); }
-
Store: The data model where we set new data and then emit events to re-render our components with the new data
AppDispatcher.register(function(action) { ... case Constants.POST_ARTICLE_DATA: var article = action.response.body if (article) { set(article); ArticleStore.emitChange(); } break; })
The application Express.js has three components.
-
Our Express server is kicked of at the /server.js file
-
A route config file can be found at /config/routes.js
app.post(path, auth.requiresLogin, articleCrud.getCreateController);
-
These routes map to our CRUD api found at /app/api/
exports.getCreateController = function (req, res) { var m = new Article(req.body); ... m.save(function (err) { ... res.send(m); } };
You can configure the application variables for Passport.js at /config/env/ and Notifier.js at /config/config.js.
To run the app on Heroku you must set the environment variables for the app.
- Set NODE_ENV to 'production'
- Set all the required variables in /config/env/production.js to empty string or live keys
- Deploy your app
*You can set config variables on Heroku with this tool.
You can find the application's tests in Two places:
- Front End tests are in the _tests_ folders located in same directory of the modules they cover
- Back end tests are located in the test directory
Run the tests with the command:
$ npm test
In production the static assets are served from the "/build" folder (In development they are served by webpack-dev-server). To use Webpack to build the JS and JSX assets into "/build/js/bundle.js" run the following:
$ npm run build
*Running build is required for changes to be seen on a production environment.
The server and mongoose models are based on those found in node-express-mongoose-demo. (Thanks to madhums)
MIT