Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Organizando o JavaScript (WebDay 2013)
Nando Vieira
July 20, 2013
Programming
20
1.1k
Organizando o JavaScript (WebDay 2013)
Palestra apresentada no WebDay 2013
Nando Vieira
July 20, 2013
Tweet
Share
More Decks by Nando Vieira
See All by Nando Vieira
fnando
8
1.3k
fnando
3
480
fnando
24
2.5k
fnando
4
550
fnando
35
1.8k
fnando
11
500
fnando
36
1.7k
fnando
31
2.8k
fnando
20
860
Other Decks in Programming
See All in Programming
minamijoyo
3
510
mehowte
0
180
grapecity_dev
0
190
konstantin_diener
0
130
oracle4engineer
0
110
ianaya89
1
200
pirosikick
4
950
legalforce
PRO
0
630
ntaro
0
170
raulh82vlc
1
150
lovee
2
200
keeeeen
0
100
Featured
See All Featured
philhawksworth
190
17k
jcasabona
8
550
hatefulcrawdad
257
17k
shpigford
165
19k
lara
172
9.6k
jeffersonlam
329
15k
morganepeng
18
1.2k
cassininazir
347
20k
brettharned
93
3k
bkeepers
408
58k
aarron
257
36k
keavy
107
14k
Transcript
Or anizando o JavaScript Nando Vieira
Nando Vieira http://simplesideias.com.br @fnando
hellobits.com empresa
howtocode.com.br cursos
codeplane.com.br it hostin
* * *
O JavaScript passou por al umas revoluções durante o seu
tempo de vida.
2004 Primeira revolução Goo le lançou o Gmail com uso
de AJAX
2006 Se unda revolução John Resi lançou o jQuery em
um meetup em NY.
2009 Terceira revolução Ryan Dahl lançou o Node.js
O JavaScript é a lin ua em mais importante da
atualidade.
Dos 50 repositórios mais populares do Github, 29 repositórios são
relacionados a JavaScript.
O JavaScript já tem quase 20 anos de idade.
Por que a ente ainda escreve códi os ruins?
"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": ""
A solução é modularidade.
Só a modularidade permitirá separar as responsabilidades do seu códi
o.
Só a modularidade tornará possível expandir o seu códi o
com facilidade.
Só a modularidade tornará possível a manutenção do seu codebase.
De quebra você ainda anha reusabilidade de componentes.
E é somente assim que o seu códi o poderá
ser testado sem dificuldades.
Se temos todos esses benefícios, porque ainda não escrevemos códi
os dessa maneira?
A verdade é que a maioria dos desenvolvedores não sabe
como fazer isso.
E porque escrever códi os modulares pode ser difícil.
Então, como fazer?
Conhecimento
Conheça a lin ua em.
http://developer.mozilla.or
http://howtocode.com.br
http://w3scho… melhor não!
http://w3fools.com
Or anização
Pense no seu códi o como uma série de blocos
que precisam encaixar uns nos outros.
None
None
None
None
None
None
Muitos outros componentes serão criados à partir dessa estrutura.
Pense em como esses blocos irão se comunicar através de
uma API pública.
Não referencie objetos diretamente do DOM, nem acesse outros objetos
lobais.
Passe todas as dependências como ar umentos da função construtora.
Cada um desses blocos pode ter o seu próprio arquivo.
É melhor ter muitos arquivos pequenos do que poucos arquivos
randes.
javascripts application.js eden AddToRe istry.js ProductInfo.js modules UserRe istries.js addToCartModule.js
addressListModule.js boletoModule.js cartReviewModule.js cate oryInterests.js cate oryModule.js checkoutModule.js
Lembre-se que você sempre pode concatenar e minificar o seu
códi o antes de colocar em produção.
Modularização
O JavaScript possui al umas alternativas diferentes para a criação
de módulos.
Você pode utilizar a ideia de namespaces com object literals.
var Todo = { tasks: [] , addTask: function(task) {}
, removeTask : function() {} , count : function() {} };
Object literals são muitos simples de utilizar, mas se comportam
mais como sin letons.
O Module pattern permite simular a escopo e visibilidade de
atributos.
var Todo = (function(){ var tasks = []; // private
variable // expose the public API return { addTask: function(task) {} , removeTask: function(task) {} , count: function() {} }; })();
O Module pattern também permite fazer a injeção de dependências.
var Todo = (function($, hb){ // all your code here
})(jQuery, Handlebars);
Eu costumo usar uma variação de Module pattern com namespace.
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 }; });
http:// ithub.com/fnando/module.js
Dependência entre os módulos não é um problema.
Utilize a aborda em sin le entry point.
// boot.js $(function(){ var html = $("html") , controller =
html.data("controller") , action = html.data("action") ; MyApp.Application(controller, action); });
Existem outras alternativas de módulos como AMD e CommonJS.
Já existe um draft de módulos nativos no JavaScript no
ES6 Harmony.
module Todo { var tasks = []; // private variable
// expose the public API export default { addTask: function(task) {} , removeTask: function(task) {} , count: function() {} }; }
module Todo { var tasks = []; // private variable
// expose the public API export default { addTask: function(task) {} , removeTask: function(task) {} , count: function() {} }; }
import Todo from Todo; Todo.addTask(task);
Os módulos podem ser importados através de URLs.
// 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 });
Você pode ser específico sobre o que quer importar.
import { a, b, c } from "some/file";
Ainda está em discussão. http://fnando.me/jp
Exemplo
Vamos implementar um postbox. http://fnando.me/jq
None
Primeiro implemente a funcionalidade do jeito mais rápido, para entender
o problema.
$(".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"); } }) ;
$(".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"); } }) ;
$(".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"); } }) ;
$(".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"); } }) ;
Depois que você conse uiu entender o problema, escreva uma
solução mais modular.
Module("HOWTO.Postbox", function(Postbox){ Postbox.fn.initialize = function(container) { this.container = container; this.textarea
= container.find(".pb-input"); this.button = container.find(".pb-button"); }; });
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)) ; }; });
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") ; }; });
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"); } }; });
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"); } }; });
Sempre que você escreve códi os mais modulares, é muito
mais simples escrever testes.
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 });
Finalizando
Todo aplicativo complexo deve ser quebrado em pedaços menores.
Você nunca sabe qual vai ser o tamanho do seu
projeto.
Códi os modulares podem ser escritos sem o uso de
bibliotecas.
Mas use o que for melhor para o seu workflow.
Obri ado!
* * *
http://howtocode.com.br