Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScript: Restoring the Sanity with AMD

Avatar for Bryan Dragon Bryan Dragon
February 07, 2013

JavaScript: Restoring the Sanity with AMD

Presentation for Fort Collins Internet Pros meetup group. View the demo app here: https://github.com/bryandragon/fcip-amd

Avatar for Bryan Dragon

Bryan Dragon

February 07, 2013
Tweet

Other Decks in Technology

Transcript

  1. JavaScript: Restoring the Sanity with AMD Bryan Dragon Web Applications

    Engineer Triad Interactive, Inc. [email protected] Thursday, February 7, 13
  2. SimNet • In-browser Microsoft Office simulation for higher ed instructors

    and students • In use at over 300 colleges & universities • Comprised of several Flex/AS3 apps • Simulations defined in XML • A single exam simulation might need to load up to 8,000 icons Thursday, February 7, 13
  3. The Flash Platform • The compiler! • Solid set of

    OO features, strong typing • E4X • Flash Player eliminates cross-browser concerns • But, alas... Flash is a dying beast. Thursday, February 7, 13
  4. JavaScript • It’s everywhere • No learning curve • Browser

    debugging tools are getting better • Leverage increasingly capable browsers • Explosive growth of frameworks & libraries Thursday, February 7, 13
  5. JavaScript jQuery Underscore Backbone Express Mocha Jasmine Dojo Ext JS

    Prototype require.js d3 Moment.js jQuery UI Raphael mustache.js Sinon.js Angular.js SproutCore Mongoose Ember.js Node.js Rhino curl.js Connect Modernizr less.js Meteor CoffeeScript Zepto async Jade Knockout Thursday, February 7, 13
  6. JavaScript: The Bad • No standard library • No scope

    isolation or dependency management • No package management • • typeof null // “object” MyClass.prototype.doFoo.apply(this, arguments); Thursday, February 7, 13
  7. Hops or Not • Full-stack JavaScript app • Express and

    Mongoose in the back • jQuery, Underscore and Backbone up front Thursday, February 7, 13
  8. 25¢ Tour of Backbone.js • Lightweight, flexible, customizable • ~

    6K min/gzip • Requires Underscore.js • Integrates with jQuery/Zepto • Push state/history management • Serialization + deserialization Thursday, February 7, 13
  9. 25¢ Tour of Backbone.js • M-V-Sorta framework • Gives you:

    Model, Collection, View, Router • M = Model, Collection • V = templates • C = Router, View Thursday, February 7, 13
  10. 25¢ Tour of Backbone.js GET /api/beers/rated AppRouter RatedView rated-view.html BeerCollection

    rated() fetch() initialize() “route:rated” 1 2 3 4 5 Thursday, February 7, 13
  11. 25¢ Tour of Backbone.js GET /api/beers/rated AppRouter BeerCollection rated() fetch()

    initialize() “route:rated” 1 2 3 4 5 6 [{“name”:”Red Banshee”}, ...] RatedView rated-view.html Thursday, February 7, 13
  12. 25¢ Tour of Backbone.js GET /api/beers/rated AppRouter RatedView rated-view.html BeerCollection

    rated() fetch() initialize() “reset” “route:rated” 1 2 3 4 5 6 7 [{“name”:”Red Banshee”}, ...] Thursday, February 7, 13
  13. 25¢ Tour of Backbone.js GET /api/beers/rated AppRouter RatedView rated-view.html BeerCollection

    rated() fetch() initialize() “reset” “route:rated” BeerThumbnailView beer-thumbnail-view.html render() 1 2 3 4 5 6 7 8 [{“name”:”Red Banshee”}, ...] Thursday, February 7, 13
  14. 25¢ Tour of Backbone.js GET /api/beers/rated AppRouter RatedView rated-view.html BeerCollection

    rated() fetch() initialize() “reset” “route:rated” BeerThumbnailView beer-thumbnail-view.html render() 1 2 3 4 5 6 7 8 render() 9 [{“name”:”Red Banshee”}, ...] Thursday, February 7, 13
  15. The Problems • Developer must specify script tags for dependencies

    in correct order (e.g., jQuery before bootstrap) • Does not scale • Pollutes the global namespace • noConflict(), anyone? Thursday, February 7, 13
  16. The Build Step • Plenty of options: • Google Closure

    compiler • Yahoo! Compressor • UglifyJS $ java -jar compiler.jar \ --js public/js/models/beer.js \ --js public/js/models/beer-collection.js \ --js_output_file public/js/app.min.js Thursday, February 7, 13
  17. The Build Step • In development we don’t want to

    build every time we update a file • We still need to solve the load order problem Thursday, February 7, 13
  18. AMD The Asynchronous Module Definition API specifies a mechanism for

    defining [JavaScript] modules such that the module and its dependencies can be asynchronously loaded. This is particularly well suited for the browser environment where synchronous loading of modules incurs performance, usability, debugging, and cross-domain access problems. Source: http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition “ Thursday, February 7, 13
  19. CommonJS • Collection of proposed standards • Defines specs for

    a module system and interoperability among modules • Many CommonJS module-compliant libraries in use today Thursday, February 7, 13
  20. AMD • Several AMD-compliant loaders available • We’re going to

    look at require.js • AMD provides for two globals: • require() • define() Thursday, February 7, 13
  21. AMD Loader Plugins • CommonJS specs also provide for AMD

    loader plugins • Allows for loading non-JS dependencies asynchronously, e.g., HTML templates • Can be referenced in a module ID using special syntax: “loader-plugin-name!target-resource” Thursday, February 7, 13
  22. Make Your Library AMD-Compliant • Library authors can check for

    AMD loaders and define their libraries as AMD modules Thursday, February 7, 13
  23. r.js • Build tool for optimizing AMD-compliant scripts • Runs

    in Node or Rhino • First runs dependency tree through require.js to determine order • Then concatenates source • Then minifies with UglifyJS Thursday, February 7, 13
  24. r.js • An optimized AMD loader can be used with

    optimized scripts • almond.js (~ 1K min/gzip) Thursday, February 7, 13
  25. Benefits of AMD • Eliminate manual, fragile load order issue

    • Keep code organized in logical units • Build re-usable components • Don’t pollute the global namespace • Easy to control scope Thursday, February 7, 13
  26. AMD: The Downside • Some dislike the idea of wrapping

    modules with define() boilerplate • Some believe it should be a language-level change, instead of an external solution • Many HTTP requests unless using a build tool, such as r.js Thursday, February 7, 13