Demo web stack using node.js, express, isomorphic react. The modules used were fashionable in Spring/Summer 2015.
Note: currently under development, not yet ready for use!
This demo was developed using node v0.12.4. You may want to use creationix/nvm to run this version of node.
npm install
Mongodb is the default db for sessions and for the app data model.
./vendor/mongodb/bin/download-mongodb.sh
./vendor/mongodb/bin/install-mongodb.sh
Redis can be used as the db for sessions, but mongodb must be run for the app data model.
./vendor/redis/bin/download-redis.sh
./vendor/redis/bin/install-redis.sh
Copy the config/environment.js.default to config/development.js or other environments as needed.
One key configuration that is required in order to login is to set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET after setting up your Google OAuth2 access.
If it is run on a modern unix system, this demo contains all of what you need to edit code, to run mongodb and redis, and to run the web stack.
Run the following shell script in order to start a screen session for developing on this code base:
./devel/bin/start_dev_screens.sh
To destroy the dev screen session (make sure files are closed):
./devel/bin/stop_dev_screens.sh
./vendor/mongodb/bin/start-mongodb.sh
./vendor/redis/bin/start-redis.sh
node devel.js
Note 1: Isomorphic mode is disabled by default in dev mode, allowing for React debugging to occur in the client.
Note 2: the files are being watched in order to rebuild client javascript and to restart the web service.
./devel/bin/build.sh
If you want more control instead of waiting for watched files to activate a client rebuild, you can manually rebuild. See the Gulpfile.js to see what happens during the build.
node app.js
Note 1: Isomorphic mode is enabled by default, meaning that React is rendered on the server-side, and then re-rendered once React is initialized in the client.
This is demoware, illustrating some interesting techniques for coding high-performance web apps.
This demoware is dated, the fashion of yesteryear. Beware: they will mock you in the street and shun you from all of the good parties if you write an app like isomorphic-react-demo-ss2015 today.
Learn to Use the New Router in ExpressJS 4.0
The future of web apps is — ready? — isomorphic JavaScript
Serverside React Rendering: Isomorphic JavaScript with ReactJS + Node by David Wells, who created an important example app that parts of this demo are based on.
Simpler UI Reasoning with Unidirectional Dataflow and Immutable Data
Why is React's concept of Virtual DOM said to be more performant than dirty model checking?
Virtual DOM and diffing algorithm
This is an idea that the author has been exploring. Read the special note about the application structure to find out more.
The node_modules season of Spring/Summer 2015 was très mémorable in SF and in SV. Documentation for the specific versions used is listed below (where possible).
Gulp is used to rebuild the client js file, including server-side React JSX rendering.
Note: this is a very old version of Jade and will soon be updated to something more recent.
Note: Pete Hunt has deprecated petehunt/node-jsx in favor of Meettya/node-jsx-babel, a fork that targets React v0.14. This demo targets React v0.13, and therefore uses petehunt/node-jsx. A future version of this demo will use Meettya/node-jsx-babel.
The application data model uses Mongoose to interact with MongoDB.
The "Isomorphic React" aspect of this demo is based on davidwells/isomorphic-react-example. Special thanks to David Wells!
Created and maintained by Jamie Pitts.
The code of this demo is organized around developer concerns, embodied in entities like users and items. This is in contrast to organizing around technical concerns such as controllers, routes, models, etc).
This structure is called Concern-Oriented Programming, the culmination of years of building web apps using frameworks and from scratch.
The key idea behind COP is that code structure should follow "who" and "what" the app is built for, as opposed to "how" the app works. In a COP app, an entity directory would contain all client, server, and data model code relating to that general concern. This essentially flattens the file structure.
In common code structuring, web app directories and file naming say a lot about the role of the code therein. As more code is added to handle new developer concerns, the repo becomes cluttered with numerous, unrelated files.
app.js
|
|- routes
| |- item.js
| |- user.js
|
|- models
| |- ItemModel.js
| |- UserModel.js
| |- UserGroupModel.js
|
|- views
| |- item_edit.jade
| |- user_edit.jade
|
|- public
| |- js
| |- item_client.js
| |- user_client.js
In this case, a developer must deal with files in four directories to add or modify user functionality.
app.js
|
|- entities
| |
| |- item
| |- client.js
| |- express_routes.js
| |- express_handlers.js
| |- item_edit.jade
| |- ItemModel.js
|
| |- user
| |- client.js
| |- express_routes.js
| |- express_handlers.js
| |- user_edit.jade
| |- UserModel.js
| |- UserGroupModel.js
|
|- public
| |- js
| |- client.js (compiled from item and user client files)
In this case, the developer would be primarily editing files in one directory. When an entity component must interact with another entity, it is very clear when that line is being crossed.
Cross-cutting concerns might be better understood within a COP app. The author is not yet certain about this, but intuitively it seems so.
Three main advantages come from loosely structuring the app around entities:
This helps new developers figure things out more quickly, and reduces the costs of maintenance.
Agreeing to boundaries in an app and code commits are also simplified.
For example, a user entity that depends on Express 4 / jade / React can be checked out into another project that depends on the same modules. In the future, json can describe how one entity's components may depend on another entity's components, and incorporate versioning.
This remains to be seen.
Packing files together that have different functional roles may seem inconsistent. The lack of a directory hierarchy means that the underlying structure of the application may be harder to guess at. Developers may be too free to create strange naming conventions.
Any of these factors can make developers sad.