General Assembly Workshop: Advanced JavaScript

Post on 11-May-2015

4,672 views 5 download

Tags:

transcript

Master Class:Isomorphic JavaScript

Spike Brehm@spikebrehm

irst, introductions.

Spike BrehmSoftware Engineer

Airbnb 2.5 years

JavaScript & Ruby

No CS background;self-taught hacker

My team

My team

My team

Introduce yourselves.

you are.Wo

you work.Were

you’re here.Wy

Agenda

...TF is Isomorphic JavaScript?Wat

...is it relevant to web developers?Wy

...can I build isomorphic apps?How

WTF is Isomorphic JavaScript?

JavaScript code that can run on both the client and server.

A brief note on “isomorphic”.

“monomorphic”“heteromorphic”“homomorphic”“multi-platform”

You’re using it wrong!

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-serer, thin-client.

ClientJavaScript

SererRubyPythonJavaPHP

Persistence

View layer

Application logic

Routing

DOM manipulation

Form validation

Animations

Circa 2011:thin-serer, fat-client.

Routing

View layer

SererRubyPythonJavaPHP

Persistence

ClientJavaScript

Application logic

DOM manipulation

Form validation

Animations

Teh footure:shared, fat-serer, fat-client.

SererRubyPythonJavaPHP

Persistence

ClientJavaScript

Routing

View layer

Application logic

DOM manipulation

Form validation

SharedJavaScript

Animations

Isomorphic JavaScript can be

orshimmed per environment .

environment-agnostic

Does not depend on browser-specific properties (window) or server-specific properties (process.env, req.cookies).

Environment-agnostic

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>

Provides shims for accessing environment-specific properties so module can expose a single API.

window.location.pathnamevs.req.path

Shimmed per environment

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.

•Templating•Routing• I18n•Date & currency formatting•Model validation•API interaction• ...?

Isomorphic use cases.

Most of your favorite libraries can be used isomorphically.

•Underscore.js•Backbone.js•Handlebars.js• jQuery•Moment•React.js•Polyglot.js (I18n)

Wy go to the trouble?

Initial pageload speed.Performance

Crawlable single-page apps.SEO

Reduce code duplication.Maintainability

Isomorphic JavaScript is a spectrum.

Entire view layer and app

logic shared

Small bits of view layer or logic shared

Many abstractions

Few abstractions

ComplexSimple

View layer shared

Entire app runtime synced between client

& server

Isomorphic frameworks.

MojitoOne of the first isomorphic frameworks.• Released by Yahoo! a few years ago.• Full-stack framework; YUI components.• Super-advanced deferred rendering.• Never caught on.

MeteorAwesome framework for building real-time apps.• Full web application framework; has own

build system and package manager.• Realtime from the ground up.• Requires MongoDB (or adapter).• No server-side rendering (yet).• All-star dev team.

RendrLibrary for isomorphic Backbone.js + Handlebars.js.

• Render your Backbone apps on the server.• Open-sourced by Airbnb.• Less opinionated than the big frameworks.• Came out of m.airbnb.com.

Building and bundling.

Package up CommonJS modules for the browser.

Browserif

Use ‘require()’ in the browser, the same way you would on the server.

Bundles a module and all its dependencies.

Browserif

demo

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

Grunt

Any questions thus far?

Hack time.

Combines a few modules together for MVP of isomorphic app.

Sample Node.js app

Express.js blog platformBasic web server with RESTful API.

Templating.Handlebars.js

DirectorRouting HTTP and HTML5.

HTTP requests to API.Superagent

Tour of the app.

Setting up locally.

git clone git@github.com:spikebrehm/isomorphic-tutorial.git

Clone the sample app

github.com/spikebrehm/isomorphic-tutorial

Ensure Node >= 0.8.x$ node --versionv0.10.21

github.com/spikebrehm/isomorphic-tutorial

Have to install?$ brew install nodeorhttp://nodejs.org

$ npm install grunt-cli -g

Install `grunt-cli`

github.com/spikebrehm/isomorphic-tutorial

$ cd isomorphic-tutorial$ npm install

Run `npm install`

github.com/spikebrehm/isomorphic-tutorial

$ grunt server

Run the serer!

github.com/spikebrehm/isomorphic-tutorial

View `localhost:3030` in browser

Let’s add a feature.

Date formattingBefore:After:

Momentmoment('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 helperPosted at {{created_at}}

Posted at {{formatDate created_at}}

function formatDate(dateStr) { return moment(dateStr).format('LLLL');}

That wasn’t so hard.Let’s do another.

Create a new postNew page at /posts/new

Form for post data

On submit, POST to the API.

Use JavaScript to intercept thesubmit event and POST via XHR.

Moar features!

Markdown formattingUsing Showdown.js.

Swap out templatingJade, EJS, Underscore, React.js.

Make it prettyBootstrap that shit. Responsive?

Add UI librarBackbone.js, Angular.js.

Towards an isomorphic future.

JavaScript is the lingua franca of the Web.

The Web is the platform;JavaScript provides the runtime.

More reusable solutions;more small modules.

It will be rare to see a web app using no server-side JavaScript.

The revolution will come in the build systems.

Static analysis, conditional builds, source transforms.

Questions?

@AirbnbNerds@spikebrehm

Thanks!