Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Modularização de código JS
Search
Rafael Macedo
October 18, 2014
Programming
240
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Modularização de código JS
Rafael Macedo
October 18, 2014
More Decks by Rafael Macedo
See All by Rafael Macedo
TDC 2014 - Solucionando o problema de Uploads em Apps no Heroku
macedorafael
1
170
GuruSP - Solucionando o problema de Uploads em Apps no Heroku
macedorafael
2
120
Aplicações Realtime com XMPP
macedorafael
3
220
Web in the cloud with ruby
macedorafael
2
400
Other Decks in Programming
See All in Programming
LLM Plugin for Node-REDの利用方法と開発について
404background
0
160
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
130
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
130
タクシーアプリ『GO』の バックエンド開発のおける AI利活用と若者のすべて
pyama86
3
1.9k
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
250
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
110
net-httpのHTTP/2対応について
naruse
0
450
GitHub Copilot CLIのいいところ
htkym
2
1.3k
dRuby over BLE
makicamel
2
320
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
230
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
17
6.1k
Inside Stream API
skrb
1
650
Featured
See All Featured
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.6k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
410
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
150
Evolving SEO for Evolving Search Engines
ryanjones
0
210
Java REST API Framework Comparison - PWX 2021
mraible
34
9.3k
Darren the Foodie - Storyboard
khoart
PRO
3
3.4k
Building an army of robots
kneath
306
46k
A better future with KSS
kneath
240
18k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
600
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Transcript
MODULARIZAÇÃO DE CÓDIGO JS @macedorafael
RAFAEL MACEDO github.com/macedo twitter.com/macedorafael
None
None
None
None
CODE MINER
CODE MINER
[email protected]
None
http://github.com
6 dos 10 projetos mais populares
560k repositórios criados em 2014* *até o momento 10/10/2014
JS deixou de ser a segunda linguagem a algum tempo
“JS may look familiar…
… but it really isn’t. Take your time to get
to know it.” @goloroden
None
application.js app/assets/javascripts/
//= require modernizr //= require jquery //= require jquery.validate //=
require jquery.validate.additional-methods //= require jquery_ujs //= require fancybox //= require_self //= require jquery.ui.datepicker //= require jquery.ui.draggable //= require underscore //= require jquery.tokeninput //= require application/browser_selector //= require application/jQuery_gtSlider //= require application/jQuery_gtSelect //= require application/bxslider //= require application/jquery.form //= require application/validations //= require jquery_nested_form //= require ckeditor/init //= require ckeditor/config //= require application/jquery.nicescroll //= require custome_js/user_journey //= require application/album_images //= require application/home //= require application/user //= require jquery.rating //= require jquery.imagedrag.min //= require slider/jssor.core //= require slider/jssor.slider //= require slider/jssor.utils //= require scroll_paginate //= require destination //= require magicselection //= require jquery.quicksearch //= require jquery.blockUI $(document).on('click','.star',function(){ $(this).parents('form:first').submit(); }); $(document).ready(function() { $('#rateform :radio.star').rating({cancel: 'Cancel', cancelValue: '0'}); $("a.fancybox").fancybox({ 'transitionIn' : 'none', 'transitionOut' : 'none', 'autoScale' : false, 'type' : 'iframe',
allowfullscreen : 'true', allowscriptaccess : 'always', closeBtn : false }).trigger('click');
$("#from_date").datepicker({ dateFormat: 'dd/mm/yy', changeMonth: true, changeYear: true }); $("#to_date").datepicker({ dateFormat: 'dd/mm/yy', changeMonth: true, changeYear: true }); }); $(document).on('click', '.bt-deletar', function(){ $(this).parents('li').remove(); }); // Hover box editar perfil function hover_perfil_box() { if ($('.lista-lugares').size() > 0) { $(".lista-lugares li").on('mouseover',function (e){ e.preventDefault(); $(this).children(".details").stop().animate({ "top": "94px" }, "fast" ); }); $(".lista-lugares li").on('mouseleave',function (e){ e.preventDefault(); $(this).children(".details").stop().animate({ "top": "120px" }, "fast" ); }); } } $(document).on('click', '.unblock_user', function(){ $(this).parents('li').addClass('none'); }); $(document).on('click','a.circle, div.msg-content-box',function(){ $(this).parents('div.msg-content-box').removeClass('read'); $(this).removeClass('read'); }); $(document).on('click','a.folder, a.del',function(){ id = $(this).parents('div.msg-content-box').prop('id') $("div[id="+id+"]").fadeOut("slow") $.fancybox.close();
allowfullscreen : 'true', allowscriptaccess : 'always', closeBtn : false }).trigger('click');
$("#from_date").datepicker({ dateFormat: 'dd/mm/yy', changeMonth: true, changeYear: true }); $("#to_date").datepicker({ dateFormat: 'dd/mm/yy', changeMonth: true, changeYear: true }); }); $(document).on('click', '.bt-deletar', function(){ $(this).parents('li').remove(); }); // Hover box editar perfil function hover_perfil_box() { if ($('.lista-lugares').size() > 0) { $(".lista-lugares li").on('mouseover',function (e){ e.preventDefault(); $(this).children(".details").stop().animate({ "top": "94px" }, "fast" ); }); $(".lista-lugares li").on('mouseleave',function (e){ e.preventDefault(); $(this).children(".details").stop().animate({ "top": "120px" }, "fast" ); }); } } $(document).on('click', '.unblock_user', function(){ $(this).parents('li').addClass('none'); }); $(document).on('click','a.circle, div.msg-content-box',function(){ $(this).parents('div.msg-content-box').removeClass('read'); $(this).removeClass('read'); }); $(document).on('click','a.folder, a.del',function(){ id = $(this).parents('div.msg-content-box').prop('id') $("div[id="+id+"]").fadeOut("slow") $.fancybox.close(); 1500 LOC
allowfullscreen : 'true', allowscriptaccess : 'always', closeBtn : false }).trigger('click');
$("#from_date").datepicker({ dateFormat: 'dd/mm/yy', changeMonth: true, changeYear: true }); $("#to_date").datepicker({ dateFormat: 'dd/mm/yy', changeMonth: true, changeYear: true }); }); $(document).on('click', '.bt-deletar', function(){ $(this).parents('li').remove(); }); // Hover box editar perfil function hover_perfil_box() { if ($('.lista-lugares').size() > 0) { $(".lista-lugares li").on('mouseover',function (e){ e.preventDefault(); $(this).children(".details").stop().animate({ "top": "94px" }, "fast" ); }); $(".lista-lugares li").on('mouseleave',function (e){ e.preventDefault(); $(this).children(".details").stop().animate({ "top": "120px" }, "fast" ); }); } } $(document).on('click', '.unblock_user', function(){ $(this).parents('li').addClass('none'); }); $(document).on('click','a.circle, div.msg-content-box',function(){ $(this).parents('div.msg-content-box').removeClass('read'); $(this).removeClass('read'); }); $(document).on('click','a.folder, a.del',function(){ id = $(this).parents('div.msg-content-box').prop('id') $("div[id="+id+"]").fadeOut("slow") $.fancybox.close(); 1500 LOC
None
None
None
3k
15k 3k
¯\_(ツ)_/¯
Modularização
• Redução de complexidade • Encapsulamento • Manutenabilidade ???
None
None
None
None
None
None
None
None
None
http://todomvc.com http://todomvc.com
MVC
Model Gerencimento de dados, persistência
View UX, renderiza templates com os dados do modelo, eventos
Controller Gerencia eventos entre models e views
None
None
http://bit.ly/1de5qfT
module revealing module mediator prototype …
module pattern
(function() { // your code here })();
var Module = (function() { // your code here })();
var Module = (function() { var privateAttribute = '';
var privateMethod = function() { /* ... */ }; })();
var Module = (function() { var privateAttribute = '';
var privateMethod = function() { /* ... */ }; })();
var Module = (function() { var privateAttribute = '';
var privateMethod = function() { /* ... */ }; return { publicMethod: function() { /* ... */ } } })();
var Module = (function() { var privateAttribute = '';
var privateMethod = function() { /* ... */ }; return { publicMethod: function() { /* ... */ } } })();
var Module = (function() { var privateAttribute = '';
var privateMethod = function() { /* ... */ }; return { publicMethod: function() { /* ... */ } } })();
var Module = (function() { var privateAttribute = '';
var privateMethod = function() { /* ... */ }; return { publicMethod: function() { /* ... */ } } })();
var QuestionsList = (function() { var collection = [1, 2,
3, 4, 5] , currentIndex = 0; return { current: function() { var i = currentIndex % collection.length; return 'Question: ' + collection[i]; }, next: function() { currentIndex += 1; }, prev: function() { currentIndex -= 1; } } })();
var QuestionsList = (function() { var collection = [1, 2,
3, 4, 5] , currentIndex = 0; return { current: function() { var i = currentIndex % collection.length; return 'Question: ' + collection[i]; }, next: function() { currentIndex += 1; }, prev: function() { currentIndex -= 1; } } })();
var QuestionsList = (function() { var collection = [1, 2,
3, 4, 5] , currentIndex = 0; return { current: function() { var i = currentIndex % collection.length; return 'Question: ' + collection[i]; }, next: function() { currentIndex += 1; }, prev: function() { currentIndex -= 1; } } })();
None
revealing module pattern
var QuestionsList = (function() { var collection = [1, 2,
3, 4, 5] , currentIndex = 0; function current() { var i = currentIndex % collection.length; return 'Question: ' + collection[i]; } function next() { currentIndex += 1; return current(); } function prev() { currentIndex -= 1; } return { current: current, next: next, prev: prev } })();
var QuestionsList = (function() { var collection = [1, 2,
3, 4, 5] , currentIndex = 0; function current() { var i = currentIndex % collection.length; return 'Question: ' + collection[i]; } function next() { currentIndex += 1; return current(); } function prev() { currentIndex -= 1; } return { current: current, next: next, prev: prev } })();
var QuestionsList = (function() { var collection = [1, 2,
3, 4, 5] , currentIndex = 0; function current() { var i = currentIndex % collection.length; return 'Question: ' + collection[i]; } function next() { currentIndex += 1; return current(); } function prev() { currentIndex -= 1; } return { current: current, next: next, prev: prev } })();
var QuestionsList = (function() { var collection = [1, 2,
3, 4, 5] , currentIndex = 0; function current() { var i = currentIndex % collection.length; return 'Question: ' + collection[i]; } function next() { currentIndex += 1; return current(); } function prev() { currentIndex -= 1; } return { current: current, next: next, prev: prev } })();
var QuestionsList = (function() { ... function _getIndex()
{ return currentIndex % collection.length; } function _incrementIndex() { currentIndex += 1; } function current() { return 'Question: ' + collection[_getIndex()]; } function next() { _incrementIndex(); return current(); } return { current: current, next: next } })();
var QuestionsList = (function() { ... function _getIndex()
{ return currentIndex % collection.length; } function _incrementIndex() { currentIndex += 1; } function current() { return 'Question: ' + collection[_getIndex()]; } function next() { _incrementIndex(); return current(); } return { current: current, next: next } })();
var QuestionsList = (function() { ... function _getIndex()
{ return currentIndex % collection.length; } function _incrementIndex() { currentIndex += 1; } function current() { return 'Question: ' + collection[_getIndex()]; } function next() { _incrementIndex(); return current(); } return { current: current, next: next } })();
Object { current: function, next: function } QuestionsList
Object { current: function, next: function, random: function } ExtraQuestionsList
var ExtraQuestionsList = (function(QuestionsList) { QuestionsList.randomQuestion() { /* ...
*/ } return QuestionList; })(QuestionsList || {});
pub/sub pattern
None
None
None
var Mediator = { obj: $({}), publish: function(event, data) {
return this.obj.trigger(event, data); }, subscribe: function(event, fn) { return this.obj.on(event, fn); }, unsubscribe: function(event, fn) { return this.obj.off(event, fn); } };
var QuestionViewer = (function(){ function onChange() { alert('current question
changed!'); // fetch new question // render ... } return { init: function() { Mediator.subscribe( 'change:question', onChange ); } } })(); QuestionViewer.init();
var QuestionsList = (function() { … function next() {
currentIndex += 1; Mediator.publish( 'change:question', { index: currentIndex } ); return current(); } … })();
AMD (Asyncronous Module Definition)
define( [ 'dep1', 'dep2' ], function(A, B) { /*
...... */ } );
define( [ "js/jquery.js", "js/jquery.color.js", "js/underscore.js" ], function($, colorPlugin, _){
var shuffleColor = _.first( _.shuffle([“#666", "#333", "#111"]) ); $( ".item" ).animate({ "backgroundColor": shuffleColor }); return {}; } );
define( [ "js/jquery.js", "js/jquery.color.js", "js/underscore.js" ], function($, colorPlugin, _){
var shuffleColor = _.first( _.shuffle([“#666", "#333", "#111"]) ); $( ".item" ).animate({ "backgroundColor": shuffleColor }); return {}; } );
define( [ "js/jquery.js", "js/jquery.color.js", "js/underscore.js" ], function($, colorPlugin, _){
var shuffleColor = _.first( _.shuffle([“#666", "#333", "#111"]) ); $( ".item" ).animate({ "backgroundColor": shuffleColor }); return {}; } );
Organização
#1 Separe módulos por arquivos
#2 Concatene e minifique os arquivos para deploy (Grunt, Gulp)
#3 Code Style (JSHint, JSLint)
#4 Escreva testes (Jasmine, Mocha)
OBRIGADO ! @macedorafael speakerdeck.com/macedorafael