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

JavaScript, Spaghetti, and Meatballs (or why modularity matters)

JavaScript, Spaghetti, and Meatballs (or why modularity matters)

My talk on JSconfBR 2013

Nando Vieira

June 22, 2013
Tweet

More Decks by Nando Vieira

Other Decks in Programming

Transcript

  1. 29 out of 50* most popular Github repositories are JavaScript-related.

    *bootstrap, node, jquery, html5-boilerplate, impress.js, d3, backbone, chosen, three.js, jQuery-File-Upload, brackets, express, angular.js, Modernizr, meteor, less.js, socket.io, jquery-mobile, underscore, reveal.js, co ee-script, jquery-ui, moment, ember.js, select2, todomvc, backbone-fundamentals, jquery-pjax, pdf.js.
  2. "invite_friends" : function() { var resizeLoader = function() { $("#loader").css("width",

    $(".places").width()); $("#loader").css("height", $(".places").height()-18); } resizeLoader(); var resizeTimer; $(window).bind('resize', function() { clearTimeout(resizeTimer); resizeTimer = setTimeout(resizeLoader, 50); }); $("a[href=#automatic_invite]").click(function(e){ SomeApp.utils.stopPropagation(e); if(!$(this).parents(".tab_title:first").is(".active")) { $(".tab_title:first") .toggleClass("active"); $(".tab_title:last") .toggleClass("active"); $("#automatic") .toggleClass("hidden"); $("#manual") .toggleClass("hidden"); } }); var suffixes = { "gmail": "@gmail.com", "yahoo": "", "live": "@hotmail.com", "other": ""
  3. var Todo = { tasks: [] , addTask: function(task) {}

    , removeTask : function() {} , count : function() {} };
  4. var Todo = (function(){ var tasks = []; // private

    variable // expose the public API return { addTask: function(task) {} , removeTask: function(task) {} , count: function() {} }; })();
  5. Module("MyApp.MyModule", function(MyModule){ MyModule.fn.initialize = function() { // this is the

    initializer }; MyModule.fn.someFunction = function() { // fn is just shortcut for // prototype alas jQuery }; });
  6. // boot.js $(function(){ var html = $("html") , controller =

    html.data("controller") , action = html.data("action") ; MyApp.Application(controller, action); });
  7. // sample.js define(function(){ var tasks = []; // private variable

    // expose the public API return { addTask: function(task) {} , removeTask: function(task) {} , count: function() {} }; });
  8. var tasks = []; // private variable // expose the

    public API module.exports = { addTask: function(task) {} , removeTask: function(task) {} , count: function() {} };
  9. module Todo { var tasks = []; // private variable

    // expose the public API export default { addTask: function(task) {} , removeTask: function(task) {} , count: function() {} }; }
  10. // load from remote sources module $ from "http://example.org/jquery.js"; //

    Module loader API Loader.load("http://example.org/jquery.js", function($){ // do what you need });
  11. $(".postbox textarea") .on("focus", function(){ $(this).closest(".postbox") .addClass("did-focus") .removeClass("is-contracted") ; }) .on("keyup",

    function(){ var lines = this.value.split(/\r?\n/); var textarea = $(this); if (lines.length >= 5) { textarea.addClass("is-taller"); } else { textarea.removeClass("is-taller"); } }) .on("blur", function(){ if (!this.value) { $(this).closest(".postbox").addClass("is-contracted"); } }) ;
  12. Module("HOWTO.Postbox", function(Postbox){ Postbox.fn.initialize = function(container) { // the initialization code

    this.addEventListeners(); }; Postbox.fn.addEventListeners = function() { this.textarea .on("focus", this.onTextareaFocus.bind(this)) .on("keyup", this.onTextareaKeyUp.bind(this)) .on("blur", this.onTextareaBlur.bind(this)) ; }; });
  13. Module("HOWTO.Postbox", function(Postbox){ Postbox.fn.initialize = function(container) {}; Postbox.fn.addEventListeners = function() {};

    Postbox.fn.onTextareaFocus = function(event) { this.container .addClass("did-focus") .removeClass("is-contracted") ; }; });
  14. Module("HOWTO.Postbox", function(Postbox){ Postbox.fn.initialize = function(container) {}; Postbox.fn.addEventListeners = function() {};

    Postbox.fn.onTextareaFocus = function(event) {}; var LINES = 5; Postbox.fn.onTextareaKeyUp = function(event) { var lines = event.target.value.split(/\r?\n/); if (lines.length >= LINES) { this.textarea.addClass("is-taller"); } else { this.textarea.removeClass("is-taller"); } }; });
  15. Module("HOWTO.Postbox", function(Postbox){ Postbox.fn.initialize = function(container) {}; Postbox.fn.addEventListeners = function() {};

    Postbox.fn.onTextareaFocus = function(event) {}; Postbox.fn.onTextareaKeyUp = function(event) {}; Postbox.fn.onTextareaBlur = function(event) { if (!event.target.value) { this.container.addClass("is-contract"); } }; });
  16. describe("HOWTO.Postbox", function() { var container, postbox, textarea; beforeEach(function() { container

    = $("<div/>") .append("<textarea class='pb-input'/>") .append("<button class='pb-button' value='Reply'/>") .appendTo("#sample") ; textarea = container.find("textarea"); postbox = HOWTO.Postbox(container); }); it("sets class when focusing box", function() { textarea.trigger("focus"); expect(container.is(".did-focus")).toBeTruthy(); }); // other specs });