KEMBAR78
Choosing a Javascript Framework | PDF
CHOOSING A JAVASCRIPT
FRAMEWORK
with Pam Selle

@pamasaur // thewebivore.com // turing.cool
AllThings Open 2015
SO… WE
WROTETHIS
THING
me,Tim Ruffles, Christopher
Hiller, and Jamie White
I will not tell you what to do.
SPOILERS!
What I will do, however
is walk you through each of the major frameworks
in the hope that you can make an informed choice for 

a project, for additional learning, or general knowledge
AGENDA
• What is a JavaScript framework?
• Major frameworks:
• Backbone
• Angular
• Ember
AGENDA
• Rising stars:
• Polymer
• React
• Framework evaluation techniques
WHAT IS A FRAMEWORK?
LONG AGO …
PEOPLE MADE WEB APPS
Okay, not that different from now
BUT
(that hasn’t changed much either)
There wasn’t “one way”
Most of the major JavaScript frameworks started in 2009/2010
As a result, frameworks emerged
–Johnny Appleseed
“Type a quote here.”
http://xkcd.com/927/
Still, JS frameworks are a very GOOD thing
Because you shouldn’t have to write a router.
Ask yourself:What’s your 15%?
MAJOR FRAMEWORKS
MAJOR FRAMEWORKS
• Backbone
• Angular
• Ember
Overview, strengths/weaknesses + a little code
BACKBONE
BASICS
• Origin story: DocumentCloud, Rails
• “Core” of an application
• “Unopinionated”
OPINIONATED?
Opinionated: there’s an obvious (or best practices-
driven) way to solve the problem.
Unopinionated:“Choose your own adventure,”
generally more flexible, ex. if incorporating other
libraries into the project.
WHATYOU GET
• Core MVC components
• Nudge in an event-driven application design
DEPENDENCIES
• Underscore
• jQuery or jQuery alternative (ex. Zepto)
STRENGTHS
• Unopinionated
• Integrates well with many libraries and backends
• Events system
WEAKNESSES
• Unopinionated
• “… that’d be your problem”
BACKBONE COMPONENTS
• Models
• Views
• Collections
• Routing
WALK-THROUGH
• Basic Model +View setup
BACKBONE MODELS
Make a model subclass using .extend( )
var	
  Property	
  =	
  Backbone.Model.extend({	
  
	
  	
  star:	
  function()	
  {	
  
	
  	
  	
  	
  this.set("starred",	
  !this.get("starred"));	
  
	
  	
  	
  	
  this.save();	
  
	
  	
  }	
  
});	
  
(code in this presentation is from the book, & final versions of sample
apps are @ github.com/pselle/choosing-javascript-framework)
BACKBONEVIEWS
.extend(), define DOM properties, render
var	
  PropertyShowView	
  =	
  Backbone.View.extend({	
  
	
  	
  tagName:	
  'div',	
  
	
  	
  className:	
  'property',	
  
	
  	
  template:	
  loadTemplate("property-­‐show"),	
  
	
  	
  render:	
  function()	
  {	
  
	
  	
  	
  	
  this.el.innerHTML	
  =	
  this.template(this.model.attributes);	
  
	
  	
  	
  	
  return	
  this;	
  
	
  	
  }	
  
});	
  
BACKBONEVIEWS
.extend(), define DOM properties, render
var	
  PropertyShowView	
  =	
  Backbone.View.extend({	
  
	
  	
  tagName:	
  'div',	
  
	
  	
  className:	
  'property',	
  
	
  	
  template:	
  loadTemplate("property-­‐show"),	
  
	
  	
  render:	
  function()	
  {	
  
	
  	
  	
  	
  this.el.innerHTML	
  =	
  this.template(this.model.attributes);	
  
	
  	
  	
  	
  return	
  this;	
  
	
  	
  }	
  
});	
  
BACKBONEVIEWS
.extend(), define DOM properties, render
var	
  PropertyShowView	
  =	
  Backbone.View.extend({	
  
	
  	
  tagName:	
  'div',	
  
	
  	
  className:	
  'property',	
  
	
  	
  template:	
  loadTemplate("property-­‐show"),	
  
	
  	
  render:	
  function()	
  {	
  
	
  	
  	
  	
  this.el.innerHTML	
  =	
  this.template(this.model.attributes);	
  
	
  	
  	
  	
  return	
  this;	
  
	
  	
  }	
  
});	
  
BACKBONEVIEWS
.extend(), define DOM properties, render
var	
  PropertyShowView	
  =	
  Backbone.View.extend({	
  
	
  	
  tagName:	
  'div',	
  
	
  	
  className:	
  'property',	
  
	
  	
  template:	
  loadTemplate("property-­‐show"),	
  
	
  	
  render:	
  function()	
  {	
  
	
  	
  	
  	
  this.el.innerHTML	
  =	
  this.template(this.model.attributes);	
  
	
  	
  	
  	
  return	
  this;	
  
	
  	
  }	
  
});	
  
BACKBONEVIEWS
Using a view with a model

var	
  myHouse	
  =	
  new	
  Property({	
  
	
  location:	
  "middle	
  of	
  our	
  street",	
  
	
  noiseLevel:	
  "usually	
  quite	
  loud"	
  
});	
  
var	
  propertyView	
  =	
  new	
  PropertyView({	
  
	
  model:	
  myHouse	
  
});	
  
propertyView.render()	
  
document.body.appendChild(propertyView.el);	
  
BACKBONEVIEWS
<div	
  class="property">

	
  	
  <h1>1123	
  Sunny	
  Road</h1>	
  
	
  	
  <h2>37890</h2>	
  
	
  	
  <img	
  src="/shared/images/
andrewmalone_house.jpg">	
  
	
  	
  <p>This	
  is	
  a	
  fantastic	
  house!</p>	
  
	
  	
  <p>Asking	
  price:	
  230000</p>	
  
	
  	
  <button	
  class="pure-­‐button	
  star">Save	
  as	
  
favorite</button>	
  
</div>
OTHER COMPONENTS
• Collections
• Groups of models
• Router
• Read/write the URL without reloading the page
OTHER COMPONENTS
• Events
• Views trigger updates to model, vice versa
• Core component of Backbone
RESOURCES
• http://backbonetutorials.com/
• http://addyosmani.github.io/backbone-
fundamentals/
• Annotated source: 

http://backbonejs.org/docs/backbone.html
ANGULAR
BASICS
• Fastest growing JavaScript framework
• Write behavior in your markup (directives)
• Google!
WHATYOU GET
• Strongly defined building components (directives,
controllers, services)
• Two-way data binding
• Dependency injection
• Auxiliary tools available: Karma, Protractor
DEPENDENCIES
• None
• Loads its own smaller jQuery

(will use your copy if provided on page, supports
2.1+)
STRENGTHS
• Short/low-context setup
• Long feature list
• Module-friendly
• Major industry backing
WEAKNESSES
• Recent rise to prominence = less time in prod
• High lock-in with writing behavior in markup
• Skeptics for future roadmap/Google backing
• 1.3 dropped IE8 support, some teams stuck in
older version now (abandonware fears)
ANGULAR KEY
COMPONENTS
• Modules
• Directives
• Services
• Controllers
MODULES
Every Angular app has 1+ module definition
var	
  realtorsapp	
  =	
  angular.module('realtorsapp',	
  []);	
  
<html	
  ng-­‐app="realtorsapp">
DIRECTIVES
Modify the behavior of the DOM (custom)
angular.module('myapp',	
  [])	
  
	
  	
  .directive('unicorn',	
  function()	
  {	
  
	
  	
  	
  	
  return	
  {	
  
	
  	
  	
  	
  	
  	
  restrict:	
  'E',	
  
	
  	
  	
  	
  	
  	
  link:	
  function(scope,	
  element,	
  attrs)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  element.html('Unicorn')	
  
	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  };	
  
});	
  
<unicorn></unicorn>
DIRECTIVES
Modify the behavior of the DOM (built in)
<table	
  ng-­‐init="properties=['123	
  Iris	
  Lane',	
  '234	
  
Sunflower	
  Blvd','923	
  Azalea	
  Rd']">	
  
	
  	
  <tr	
  ng-­‐repeat="property	
  in	
  properties">	
  
	
  	
  	
  	
  <td><a	
  href="#">{{	
  property	
  }}</a></td>	
  
	
  	
  	
  	
  <td>20001</td>	
  
	
  	
  	
  	
  <td>$1M</td>	
  
	
  	
  </tr>	
  
</table>	
  
SERVICES
• Singleton to inject into any Angular component
• Lazily instantiated
angular.module('realtorsApp')	
  
	
  	
  .factory('Properties',	
  function	
  ($http)	
  {	
  
	
  	
  	
  	
  var	
  getProperties	
  =	
  function	
  getProperties()	
  {	
  
	
  	
  	
  	
  	
  	
  return	
  $http.get('data.json')	
  
	
  	
  	
  	
  	
  	
  	
  	
  .then(function	
  (res)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  res.data.properties;	
  
	
  	
  	
  	
  	
  	
  	
  	
  });	
  
	
  	
  	
  	
  };	
  
	
  	
  	
  	
  return	
  {	
  
	
  	
  	
  	
  	
  	
  getProperties:	
  getProperties	
  
	
  	
  	
  	
  };	
  
	
  	
  });	
  
CONTROLLERS
• Controllers augment scope ($scope)
• Bind business logic to the view
angular.module('realtorsApp').controller('PropertiesController',	
  
	
  function	
  ($scope,	
  Properties,	
  $window)	
  {	
  
	
  	
  	
  Properties.getProperties()	
  
	
  	
  	
  	
  	
  //	
  chain	
  w/	
  the	
  promise	
  returned	
  by	
  getProperties()	
  
	
  	
  	
  	
  	
  .then(function	
  success(properties)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  $scope.properties	
  =	
  properties;	
  
	
  	
  	
  	
  	
  },	
  function	
  failure(err)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  $window.alert(err);	
  
	
  	
  	
  });	
  
	
  });	
  
});
CONTROLLERS
• Controllers augment scope ($scope)
• Bind business logic to the view
<table	
  ng-­‐controller="PropertyController">	
  
	
  	
  <tr	
  class="property-­‐item"	
  ng-­‐repeat="property	
  in	
  properties">	
  
	
  	
  	
  	
  <td>	
  
	
  	
  	
  	
  	
  	
  <h1><a	
  ng-­‐href="#/detail/
{{	
  property.id	
  }}">{{	
  property.streetAddress	
  }}</a></h1>	
  
	
  	
  	
  	
  	
  	
  <p>Asking	
  Price:	
  {{	
  property.price	
  |	
  currency	
  }}</p>	
  
	
  	
  	
  	
  	
  	
  <p>{{	
  property.zipCode	
  }}</p>	
  
	
  	
  	
  	
  </td>	
  
	
  	
  </tr>	
  
</table>
OTHER COMPONENTS
• Filters
• Animations
• i18n l10n
• Accessibility with ngAria
• Testing (Karma, Protractor)
(BIG) CAVEAT
• Angular 2: https://angular.io/
• TypeScript
RESOURCES
• https://docs.angularjs.org/guide/
• https://docs.angularjs.org/api/
• https://docs.angularjs.org/tutorial/
RESOURCES
• https://egghead.io (great short videos, ~$20/mo.)
• http://angular-air.com/ (live video podcast)
EMBER
BASICS
• Most complete JS framework
• Built completely on modular OSS components
• Community super-powered
WHATYOU GET
• Very strongly defined MVC components
• Data binding
• Ember Components
• Great routing support
• Dependency injection
WHATYOU GET
• Code generation with Ember CLI
• Debugging tools with Ember Inspector
DEPENDENCIES
• Node.js
• NPM
STRENGTHS
• Community!
• Convention-driven
• Commonalities with every other Ember app
• Generation tools and templates
WEAKNESSES
• SometimesTOO much information
• “Right” way to do things = difficult to get up to
speed quickly
• Not as pervasive as other two major frameworks
KEY COMPONENTS
• Templating via Handlebars
• Models
• Routes
• Components
• Controllers
WALK-THROUGH
• Getting started
• Routes
• Models
• Components
GETTING STARTED
you@xyz$	
  npm	
  install	
  -­‐g	
  ember-­‐cli	
  
you@xyz$	
  ember	
  new	
  new-­‐app	
  
you@xyz$	
  cd	
  new-­‐app	
  
you@xyz$	
  ember	
  server
GETTING STARTED
GETTING STARTED
• Dependencies
• Git
• Ready to go!
ROUTES
ember	
  generate	
  route	
  index	
  
//	
  routes/index.js	
  
import	
  Ember	
  from	
  'ember';	
  
export	
  default	
  Ember.Route.extend({	
  
	
  	
  model:	
  function()	
  {	
  
	
  	
  	
  	
  return	
  $.getJSON('/shared/data.json');	
  
	
  	
  }	
  
});	
  
	
  	
  
MODELS
export	
  default	
  Ember.Route.extend({	
  
	
  	
  model:	
  function()	
  {	
  
	
  	
  	
  	
  return	
  $.getJSON('/shared/data.json');	
  
	
  	
  }	
  
});	
  
	
  	
  
MODELS
ember	
  generate	
  model	
  post	
  title:string	
  body:string	
  
//	
  models/post.js	
  
import	
  DS	
  from	
  'ember-­‐data';	
  
export	
  default	
  DS.Model.extend({	
  
	
  	
  title:	
  DS.attr('string'),	
  
	
  	
  body:	
  DS.attr('string')	
  
});	
  
COMPONENTS
Web components!
Contain:
• Template (presentation/markup)
• Behavior (JavaScript)
DETOUR
Web components are comprised of multiple
standards that are not yet implemented across
browsers:
Custom elements, HTML imports, templates, and
shadow DOM
http://webcomponents.org/
COMPONENTS
// ember generate component my-component --pod
// components/my-component/template.hs

// components/mycomponent/component.js
{{my-component}}
RESOURCES
• Ember Guides (guides.ember.com)
• Ember Watch (emberwatch.com)
• Ember CLI 101(leanpub.com/ember-cli-101)
RISING STARS
POLYMER
POLYMER
• Web components!
• Also see: x-tags.org, from Mozilla
DETOUR: RESUMED!
• Specs
• Custom elements
• HTML imports
• Templates
• Shadow DOM
DETOUR: RESUMED!
• Webcomponents.js polyfills
• Polymer vs. web components
jonrimmer.github.io/are-we-componentized-yet/
POLYMER COMPONENT
//	
  my-­‐component.html	
  
<link	
  rel="import"	
  href="../components/polymer/
polymer.html">	
  
<polymer-­‐element	
  name="my-­‐component">

	
  	
  <template>

	
  	
  	
  	
  <style></style>

	
  	
  	
  	
  <h2>My	
  Custom	
  Component!</h2>

	
  	
  </template>

	
  	
  <script>Polymer({is:'my-­‐component'})</script>

</polymer-­‐element>	
  
<my-­‐component></my-­‐component>
POLYMER COMPONENT
//	
  my-­‐component.html	
  
<link	
  rel="import"	
  href="../components/polymer/
polymer.html">	
  
<polymer-­‐element	
  name="my-­‐component">

	
  	
  <template>

	
  	
  	
  	
  <style></style>

	
  	
  	
  	
  <h2>My	
  Custom	
  Component!</h2>

	
  	
  </template>

	
  	
  <script>Polymer({is:'my-­‐component'})</script>

</polymer-­‐element>	
  
<my-­‐component></my-­‐component>
POLYMER COMPONENT
//	
  my-­‐component.html	
  
<link	
  rel="import"	
  href="../components/polymer/
polymer.html">	
  
<polymer-­‐element	
  name="my-­‐component">

	
  	
  <template>

	
  	
  	
  	
  <style></style>

	
  	
  	
  	
  <h2>My	
  Custom	
  Component!</h2>

	
  	
  </template>

	
  	
  <script>Polymer({is:'my-­‐component'})</script>

</polymer-­‐element>	
  
<my-­‐component></my-­‐component>
POLYMER COMPONENT
//	
  my-­‐component.html	
  
<link	
  rel="import"	
  href="../components/polymer/
polymer.html">	
  
<polymer-­‐element	
  name="my-­‐component">

	
  	
  <template>

	
  	
  	
  	
  <style></style>

	
  	
  	
  	
  <h2>My	
  Custom	
  Component!</h2>

	
  	
  </template>

	
  	
  <script>Polymer({is:'my-­‐component'})</script>

</polymer-­‐element>	
  
<my-­‐component></my-­‐component>
RESOURCES
• Docs (polymer-project.org/1.0/docs)
• Web Components Weekly (webcomponentsweekly.me)
• Polymer Slack (polymer-slack.herokuapp.com)
• Polymer Podcast (www.polymerpodcast.com)
• More links (http://bit.ly/1Gc5ccI)
REACT
REACT
• Only view layer
• Shadow DOM
• Super performant
REACT COMPONENT
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
Hello, world! I am a CommentBox.
</div>
);
}
});
ReactDOM.render(
<CommentBox />,
document.getElementById('content')
);
REACT COMPONENT
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
Hello, world! I am a CommentBox.
</div>
);
}
});
ReactDOM.render(<CommentBox />, document.getElementById('content'));
SEE ALSO
• Flux - Architecture pattern
• Om - React with ClojureScript
RESOURCES
• http://reactjsnewsletter.com/
• http://reactpodcast.com/
• http://www.reactiflux.com/ :(
EVALUATING FRAMEWORKS
EVALUATIONTOOLS
• Spreadsheet for ranking: http://bit.ly/1g6kDSS
• Rank frameworks according to business, technical,
and team criteria
• Wharton DevTap: 

http://technology.wharton.upenn.edu/devtap/
THANKYOU!
@pamasaur // thewebivore.com // turing.cool
50% OFF CHOOSING A JS
FRAMEWORK BOOK
https://gum.co/OAOI/allthingsopen

Choosing a Javascript Framework