Master Class:
Isomorphic JavaScript

Spike Brehm
@spikebrehm
New iOS,
Android apps
launched
today

</marketing>
Agenda
Wat
...TF is Isomorphic JavaScript?

Wy
...is it relevant to web developers?

How
...can I build isomorphic apps?
WTF is Isomorphic
JavaScript?
JavaScript code that can run
on both the client and server.
A brief note on
“isomorphic”.
You’re using it wrong!
“monomorphic”
“heteromorphic”
“homomorphic”
“multi-platform”
Example, plz.
Example: Underscore.js
var posts = [{
id: 1,
title: 'JavaScript is cool'
}, {
id: 2,
title: 'The Web is the platform'
}];
 
_.pluck(posts, 'title');
// ['JavaScript is cool', 'The Web is the platform']
Ye olde days:
fat-serer, thinclient.
DOM
manipulation

Form
validation

Client
Animations

JavaScript

Serer
Routing
View layer
Application logic
Persistence

Ruby
Python
Java
PHP
Circa 2011:
thin-serer, fatclient.
DOM
manipulation

Form
validation

Client
Animations

JavaScript

Routing
View layer
Application logic

Serer
Persistence

Ruby
Python
Java
PHP
Teh footure:
shared, fat-serer,
fat-client.
DOM
manipulation

Form
validation

Client
Animations

JavaScript

Shared
Routing

JavaScript

View layer
Application logic

Serer
Persistence

Ruby
Python
Java
PHP
Isomorphic
JavaScript can be
environmentagnostic
or
shimmed per
environment .
Environment-agnostic
Does not depend on browserspecific properties (window) or
server-specific properties
(process.env, req.cookies).
Example: Handlebars.js
var template =
'<ul>' 
'{{#each posts}}' 
' <li>{{title}}</li>' 
'{{/each}}' 
'</ul>'
;
 
var templateFn = Handlebars.compile(template)
, html = templateFn({posts: posts});
// <ul>
//
<li>JavaScript is cool</li>
//
<li>The Web is the platform</li>
// </ul>
Shimmed per environment
Provides shims for accessing
environment-specific properties so
module can expose a single API.
window.location.pathname
vs.
req.path
Example: Superagent
superagent
.post('/api/posts.json')
.send({ title: 'Moar JavaScript', body: '...' })
.set('X-Api-KEY', '123456abcdef')
.end(function(response) {
if (response.status === 200) {
console.log("Success!");
} else {
console.error("Error", response.body.error);
}
});
Isomorphic use
cases.
Isomorphic use cases.
• Templating
• Routing
• I18n
• Date

& currency formatting
• Model validation
• API interaction
• ...?
Most of your
favorite libraries
can be used
isomorphically.
• Underscore.js
• Backbone.js
• Handlebars.js
• jQuery
• Moment
• React.js
• Polyglot.js

(I18n)
Isomorphic
JavaScript is a
spectrum.
Small bits of
view layer or
logic shared

Entire view
layer and app
logic shared
Few
abstractions

Many
abstractions
Simple

Complex
View layer
shared

Entire app
runtime synced
between client
& server
Wy go to the
trouble?
Performance
Initial pageload speed.

SEO
Crawlable single-page apps.

Maintainability
Reduce code duplication.
Building and
bundling.
Browserif
Package up CommonJS modules
for the browser.
Use ‘require()’ in the browser, the
same way you would on the server.
Browserif
// app/template_renderer.js
 
var handlebars = require('handlebars');
 
module.exports = function(templatePath, data) {
var templateFn = require('./views/' + templatePath)
, html = templateFn(data);
return html;
};

Bundles a module and all its dependencies.
Grunt
Task runner for automating build
and development workflow.
Grunt
• Compile

Handlebars templates
• Run Browserify to package up
your shared app files
• Recompile files and restart Node
server on every change
Any questions thus
far?
Hack time.
Sample Node.js app
Combines a few modules together
for MVP of isomorphic app.

Express.js blog platform
Basic web server with RESTful API.
Handlebars.js
Templating.

Superagent
HTTP requests to API.

Director
Routing HTTP and HTML5.
Tour of the app.
Setting up locally.
Clone the sample app
git clone git@github.com:spikebrehm/
isomorphic-tutorial.git

github.com/spikebrehm/isomorphic-tutorial
Ensure Node >= 0.8.x
$ node --version
v0.10.21

Have to install?
$ brew install node
or
http://nodejs.org
github.com/spikebrehm/isomorphic-tutorial
Install `grunt-cli`
$ npm install grunt-cli -g

github.com/spikebrehm/isomorphic-tutorial
Run `npm install`
$ cd isomorphic-tutorial
$ npm install

github.com/spikebrehm/isomorphic-tutorial
Run the serer!
$ grunt server

View `localhost:3030` in browser

github.com/spikebrehm/isomorphic-tutorial
Let’s add a feature.
Date formatting
Before:
After:

Moment
moment('2013-11-04T17:23:01.329Z').format('LLLL');
// "Monday, November 4 2013 9:23 AM"
Add Moment using NPM
$ npm install moment --save
Create `formatDate`
Handlebars helper
Posted at {{created_at}}
Posted at {{formatDate created_at}}

function formatDate(dateStr) {
return moment(dateStr).format('LLLL');
}
Questions?
Thanks!
@AirbnbNerds
@spikebrehm

Isomorphic JavaScript: #DevBeat Master Class