/isomorphic

Command-line interface and project structure for fast, isomorphic webapps with React + Flux

Primary LanguageJavaScriptMIT LicenseMIT

#isomorphic

###Work in Progress. Not Complete.

Command-line interface and project structure for building fast, isomorphic webapps with React + Flux.

######Install

npm install -g isomorphic
isomorphic new your-app # --todo (for example app)
cd your-app && npm install
isomorphic server

Then go to localhost:3030...or see it now at isomorphic-todo.frontendperformance.com.

Basic code implementation snippet

###What?

  • Server rendered websites provide SEO and initial page load performance*.
  • Client rendered webapps (MVx, etc.) offer a better user experience*, and are faster after the initial page load*. They struggle with SEO** and initial page load performance**.

Isomorphic webapps are single page applications that render on both the client and server (using nodejs). They are ambitious client side webapps with SEO and initial page load performance by default.

*Typically and **without jumping through hoops

###Goals

"MY SERVER WILL NEVER BE IN NODE AND I WILL NEVER USE MONGO." -- PHP CEO

Many developers turn away from Node, because full stack JavaScript (API; data) might not be feasible, or desirable. This separates the frontend Node.js server from the data layer. Both the client, and frontend server interact with a language agnostic API endpoint.

  • Provide the most 'JavaScript bang' for your 'performance buck'.
  • Simplicity. Make it easy to create high quality, highly performant isomorphic webapps.
  • Follow performance best practices: Server rendered HTML; no blocking assets; critical css.
  • Piece together simple, great tools, to provide an easy to use CLI and framework, without reinventing the wheel.
  • Smart build tools: simple CLI (scaffolding + generators); Unit testing; Gulp tasks.

Note: Your backend server can still be written in Node.js, which can of course still use Mongo.

###Libraries / Tools

######Core

React and Flux are the most important parts of this project. I'd recommend listening to this podcast; experimenting with React; and reading the concepts behind Flux architecture.

Flux is very simple: route resolves a promise via services ---> route renders React component ---> component calls action setting initial data ---> action is dispatched ---> store(s) listening to dispatch ---> store updates component ---> user clicks link ---> route resolves promise...

There are a lot of great frameworks out there. React and Flux have a lot of pros. Play around with them and see if they are best for you. Run npm install -g isomorphic && isomorphic new my-app to explore the example application.

######Tools for Single Page Apps

Small isomorphic libraries for routing (Director) and Ajax requests (SuperAgent). Isomorphic wraps these (explained below) libraries, for ease of development. Picked for size, simplicity and isomorphic support.

######Testing

Jest extends Jasmine, adding useful tools to a test suite. Tests files in */__tests__ directories, and automatically mocks dependencies, amongst other things. Picked because it takes no setup (Jasmine does), and pairs nicely with both React and Flux (Facebook tools).

######Server / Build

Frontend Node server uses express, with Stylus. This server will likely be relatively simple with the use of an external API. Support for Critical CSS by defining a critical CSS entry point in a route.

Gulp is a stream-based build tool, which is simpler, and more efficient than Grunt. Gulp tasks are defined in outside of the project scaffold, but can be overwritten on a per app basis.

######Facebook...

React, Flux and Jest are all Facebook creations. There are plenty of other great tools out there. I've tried many to varying extents, and appreciate the simplicity + power of the Facebook stack. I think React is innovative, and a fun technology to use. There is also a huge benefit in knowing these tools are battle tested on one of the worlds most trafficked sites. These libraries are powerful, and committed to performance.

###Executable

NOTE: WORK IN PROGRESS.

isomorphic new <app-name> <options...>
  --todo (Default: false)
  # --crud (Default: false)
  # --bower (Default: false)
# isomorphic init <app-name>
isomorphic server
  --environment (Default: development)
isomorphic build
  --environment (Default: development)
isomorphic gulp <task>
# isomorphic generate <type> <name>
isomorphic help <name>
# isomorphic test
isomorphic version

###Wrapper (client/server)

Include these in application JavaScript code to be used on the client and server.

var isomorphic = require('isomorphic');

// react and flux dispatcher
isomorphic.React;
isomorphic.Dispatcher;

// environment support (build options; api config)
isomorphic.environment;

// client takes over server.
isomorphic.isomorphize;

// wraps require to prefix filenames with what client/server expecting.
isomorphic.require;

// interact with api endpoint on client / server (uses Superagent)
isomorphic.request;

// promises to use with superagent in services.
isomorphic.Promise;

// initializes routes on client / server (uses Director)
isomorphic.router;

// basic performance stats
isomorphic.performance;

###Folder Structure

  */__tests__/*     # Tests -- ex: app/routes/__tests__/*
  app/*             # All server + client code
  app/client.js     # Initializes client application
  app/router.js     # Define application routes
  app/actions/*     # Flux architecture
  app/constants/*   # Link actions with dispatcher, etc
  app/components/*  # React components
  app/dispatcher/*  # Flux architecture
  app/routes/*      # Client + server routing
  app/services/*    # All requests to API endpoint
  app/stores/*      # Flux architecture
  assets/*          # CSS; Images; Fonts
  bower.json        # Manage Bower (optional)
  environment.json  # Environment / API settings
  gulpfile.js       # Overwrite gulp tasks defined in isomorphic
  index.html        # Entry point
  package.json      # Manage NPM
  server.js         # Initializes server application
  vendor/*          # Vendor Assets (Bower Managed, optional)
  .gitignore
  .jshintrc

Example Application

isomorphic new your-app --todo will install the example application.

This application is:

  1. Isomorphic -- try disabling JavaScript.
  2. Highly performant. I've seen times under 50ms total (40ms server, 10ms client).
  3. Proxies (readonly) APIs at isomorphic-todo-api.frontendperformance.com and isomorphic-crud-api.frontendperformance.com.

The todo example extends TodoMVC to show a slightly more complex application with routing, and an API.