SlideShare a Scribd company logo
Modular JavaScript Heaven
with AMD and Events
@shiota ConFoo 2015
HELLO!slideshare.net/eshiota
github.com/eshiota
@shiota
Modular and Event-Driven JavaScript
Modular and Event-Driven JavaScript
* 16/02/2015 https://github.com/search?p=1&q=stars%3A%3E1&s=stars&type=Repositories
Out of the top 50 most starred
repos in Github, 25 are
JavaScript related.
JavaScript is awesome!
Modular and Event-Driven JavaScript
But sometimes it sucks.
Modular and Event-Driven JavaScript
It may become unreadable
and unmaintainable.
(function(){
window.app = jQuery.extend({
init: function(){
tab = $('.tabs li > a.tab-toggle');
tabs = $('.tabs').find('> div');
if (tabs.length > 1){
tab.each(function (i){$(this).attr('href', '#content-' + ++i)});
tabs.each(function(i){$(this).attr('id', 'content-' + ++i)});
tabs.addClass('tab-inactive');
$('.tabs li:first-child a').addClass('state-active');
}
$('#initial-cash, #financing_value_vehicles, #tax, #bid-initial-cash, #bid-product-value').maskMoney({
thousands: '.',
decimal: ',',
allowZero: true,
allowNegative: false,
defaultZero: true
});
/** FINANCING CALCULATOR **/
$("#financing_value_vehicles").on("blur", function(){
var price = (accounting.unformat($(this).val(), ",")) || 0;
var suggestedInitialPayment = price * 0.2;
var formattedResult = accounting.formatMoney(suggestedInitialPayment, "", "2", ".", ",");
$("#initial-cash").val(formattedResult);
});
$("#calculate-financing").click(function(event){
var price = (accounting.unformat($("#financing_value_vehicles").val(), ",")) || 0;
var rate = (accounting.unformat($("#tax").val(), ",") / 100) || 0;
var initialCash = (accounting.unformat($("#initial-cash").val(), ",")) || 0;
var value = (accounting.unformat($("#amount-finance").val(), ",")) || 0;
var finance = price - initialCash;
var months = (accounting.unformat($("#prize_parcela").val(), ",")) || 0;
var tax = parseFloat(rate);
(single JS file,
173 LOC inside one function,
at least 7 different concerns)
It may become a
CALLBACK HELL
(and some libraries just make it worse)
Modular and Event-Driven JavaScript
$(document).ready(function () {
$(".submit-button").on("click", function () {
$.ajax({
url : "/create",
type : "POST",
success : function (data) {
$.each(data.created_items, function (index, value) {
var item = $("<div />").text(value);
$(".items-list").append(item).hide().fadeIn(400, function () {
setTimeout(function () {
item.fadeOut(function () {
item.remove();
});
}, 1000);
});
});
}
});
});
});
A modular, event-based
structure solves these
problems and much more.
Modular JavaScript Heaven
with AMD and Events
(on the web)
Agenda
Making it modular
Controlling the flow
Communicating through events
MODULES
Single responsability, part
of a complex system.
Modular and Event-Driven JavaScript
Isolated behaviour
and knowledge.
Modular and Event-Driven JavaScript
Testable.
Modular and Event-Driven JavaScript
Extensible and modifiable.
Modular and Event-Driven JavaScript
(good taste is optional)
May be replaced and reused.
Modular and Event-Driven JavaScript
Namespaces
Helps organising the
code in separate blocks.
///////////////////////////////
// Code for photo gallery
///////////////////////////////
var gallery = $(".gallery");
var galleryCurrent = 0;
var galleryTimer = 5000;
$(".thumbs").on("click", function (event) {
// ...
});
function goToNext () {
// ...
}
setTimeout(function () {
goToNext();
}, galleryTimer);
///////////////////////////////
// Code for switching tabs
///////////////////////////////
var tabs = $(".tabs");
tabs.on("click", function (event) {
// ...
});
function switchTab(tab) {
// ...
}
✗
MyApp.components.photoGallery($(".gallery"));
MyApp.ui.tabs($(".tabs"))
var MyApp = MyApp || {};
MyApp.components = MyApp.components || {};
MyApp.components.photoGallery = function (element) {
// ...
};
var MyApp = MyApp || {};
MyApp.ui = MyApp.ui || {};
MyApp.ui.tabs = function (element) {
// ...
};
Provides a fairly
logical structure.
/javascript
/myapp
/components
/photoGallery.js
/ui
/tabs.js
Avoids polluting the
global context.
window
$ photoGallery tabs profile login plugin
window
$ MyApp plugin
components ui sections
photoGallery tabs profile login
Module pattern
Provides a scope, and allows
"public" and "private" APIs.
MyApp.components.photoGallery = (function (window, document, $) {
// Private properties
// ------------------
var element;
var thumbs;
var current = 0;
var timer = 5000;
// Private methods
// ---------------
var goToNext = function () {
// ...
};
var setupGallery = function () {
thumbs.on("click", function () {
// ...
});
setTimeout(function () {
goToNext();
}, timer);
}
return {
// Public methods
// --------------
init : function (el) {
element = $(el);
thumbs = element.find("[data-thumbs]");
setupGallery();
}
};
})(window, document, jQuery);
MyApp.components.photoGallery
// Private properties
// ------------------
var
var
var
var
// Private methods
// ---------------
var
};
var
thumbs.on(
});
setTimeout(
goToNext();
}, timer);
}
return
init
element
thumbs
setupGallery();
}
};
})(window
// Private properties
// ------------------
var element;
var thumbs;
var current = 0;
var timer = 5000;
// Private methods
// ---------------
var goToNext = function () {
// ...
};
var setupGallery = function () {
thumbs.on("click", function () {
// ...
});
setTimeout(function () {
goToNext();
}, timer);
}
MyApp.components.photoGallery
// Private properties
// ------------------
var
var
var
var
// Private methods
// ---------------
var
};
var
thumbs.on(
});
setTimeout(
goToNext();
}, timer);
}
return
init
element
thumbs
setupGallery();
}
};
})(window
// Public methods
// --------------
init : function (el) {
element = $(el);
thumbs = element.find("[data-thumbs]");
setupGallery();
}
It's "singleton-like".
Constructors & Prototypes
Allows multiple instances of
the same behaviour, and
prototype inheritance.
Modular and Event-Driven JavaScript
B.wishlistMap.ListItem = function (element) {
this.element = $(el);
this.init();
};
B.wishlistMap.ListItem.prototype = {
init : function () {
// ...
},
expandCard : function () {
// ...
},
contractCard : function () {
// ...
}
};
var list = $("#wl-cards");
var items = list.find(".wl-card");
items.each(function () {
$(this).data("ListItem", new B.wishlistMap.ListItem(this));
});
// or
var itemsInstances = [];
items.each(function () {
itemsInstances.push(new B.wishlistMap.ListItem(this));
});
AMD
Asynchronous
Module

Definition
// photoGallery.js
define([
"jQuery",
"myapp/lib/keycodes",
“myapp/components/Map”
], function ($, keycodes, Map) {
// ...
});
Provides a consistent API
to define modules.
// photoGallery.js
define([
],
});
// photoGallery.js
define(
);
It handles dependencies.
// photoGallery.js
define([
],
});
// photoGallery.js
[
"jQuery",
"myapp/lib/keycodes",
“myapp/components/Map”
]
It injects the
dependencies in a
callback function…
// photoGallery.js
define([
],
});
// photoGallery.js
function ($, keycodes, Map) {
}
… which gives you
freedom to implement
your solution.
// Module pattern
define([
"myDependency"
], function(myDependency) {
var myPrivateMethod = function() {
};
return {
myPublicMethod : function() {
myPrivateMethod();
}
}
});
// Constructor
define([
"myDependency"
], function(myDependency) {
var MyConstructor = function() {
};
MyConstructor.prototype.myPublicMethod = function() {
};
return MyConstructor;
});
// Simple execution
define([
"myDependency"
], function(myDependency) {
// do something
});
Whatever is returned by the
callback will be injected when
the module is required.
myapp/
components/
myComponent.js
define(function() {
return "foobar";
});
myapp/
components/
anotherComponent.js
define([
"myapp/components/myComponent"
], function(myComponent) {
console.log(myComponent === "foobar"); // true
})
You can also assign an
object literal to the module.
define({
color : "yellow",
size : "medium",
quantity : 2
});
Modules are defined
by their path…
/myapp
/components
photoGallery.js
define(function() {
});
/myapp
/components
anotherComponent.js
define([
"myapp/components/photoGallery"
], function(photoGallery) {
});
/myapp
/components
anotherComponent.js
define([
"./photoGallery"
], function(photoGallery) {
});
… or by their identifier.
define(“MyApp.components.photoGallery", function() {
});
define("MyApp.components.anotherComponent", [
"MyApp.components.photoGallery"
], function(photoGallery) {
});
// jQuery does this internally
define("jquery", function() { return jQuery; });
You can also use the
require method.
var photoGallery = require("MyApp.components.photoGallery");
photoGallery.init();
require(["MyApp.components.photoGallery"], function(photoGallery) {
photoGallery.init();
});
Its behaviour depends on
the AMD implementation.
RequireJS vs. Almond
Modular and Event-Driven JavaScript
RequireJS allows
asynchronous
module loading.
<script src="javascript/require.js" data-main="javascript/myapp/app"></script>
Modular and Event-Driven JavaScript
Be REALLY careful
with that.
r.js optimises and
combines dependencies.
(be careful with dynamic
module requests)
// won't work
require(['section/' + section]);
Modular and Event-Driven JavaScript
Lean, 1kb AMD loader.
It expects all
modules to be
already loaded.
<script src="javascript/almond.js"></script>
<script src="javascript/vendor/jquery-1.11.2.js"></script>
<script src="javascript/vendor/EventEmitter.js"></script>
<script src="javascript/myapp/components/photoGallery.js"></script>
<script src="javascript/myapp/components/myComponent.js"></script>
<script src="javascript/myapp/section/login.js"></script>
<script src="javascript/myapp/section/profile.js"></script>
<script src="javascript/myapp/ui/dropdown.js"></script>
<script src="javascript/myapp/ui/tabs.js"></script>
<script src="javascript/myapp/core/sectionInitializer.js"></script>
<script src="javascript/myapp/app.js"></script>
<script src="javascript/almond.js"></script>
<script src="javascript/app-41884634e80f3516.js"></script>
It expects all modules
to have a name.
define("myModule", [
"myDependencyA",
"myDependencyB"
],
function() {
});
Since all modules are
loaded, you can use
the simple require
function anywhere.
var photoGallery = require("MyApp.components.photoGallery");
photoGallery.init();
Gives the AMD
syntax without
extra headaches.
It (probably) works
with your existing
codebase.
APPLICATION FLOW
Single entry points
(function(){
window.app = jQuery.extend({
init: function(){
tab = $('.tabs li > a.tab-toggle');
tabs = $('.tabs').find('> div');
if (tabs.length > 1){
tab.each(function (i){$(this).attr('href', '#content-' + ++i)});
tabs.each(function(i){$(this).attr('id', 'content-' + ++i)});
tabs.addClass('tab-inactive');
$('.tabs li:first-child a').addClass('state-active');
}
$('#initial-cash, #financing_value_vehicles, #tax, #bid-initial-cash, #bid-product-value').maskMoney({
thousands: '.',
decimal: ',',
allowZero: true,
allowNegative: false,
defaultZero: true
});
/** FINANCING CALCULATOR **/
$("#financing_value_vehicles").on("blur", function(){
var price = (accounting.unformat($(this).val(), ",")) || 0;
var suggestedInitialPayment = price * 0.2;
var formattedResult = accounting.formatMoney(suggestedInitialPayment, "", "2", ".", ",");
$("#initial-cash").val(formattedResult);
});
$("#calculate-financing").click(function(event){
var price = (accounting.unformat($("#financing_value_vehicles").val(), ",")) || 0;
var rate = (accounting.unformat($("#tax").val(), ",") / 100) || 0;
var initialCash = (accounting.unformat($("#initial-cash").val(), ",")) || 0;
var value = (accounting.unformat($("#amount-finance").val(), ",")) || 0;
var finance = price - initialCash;
var months = (accounting.unformat($("#prize_parcela").val(), ",")) || 0;
var tax = parseFloat(rate);
var nominator = (Math.pow(1 + tax, months));
var denominator = ((Math.pow(1 + tax, months)) - 1);
var formattedFinance = accounting.formatMoney(finance, "", "2", ".", ",");
$("amount-finance").val(formattedFinance);
var financingValue = finance*nominator*tax/denominator;
var result = accounting.formatMoney(financingValue, "R$ ", "2", ".", ",");
$(".calculator_financing li.result p.value").text(result);
this.button = $("#calc");
if( result != ""){
$("a.button").remove();
this.button.after("<a href='financiamento/new?vehicle_value="+price+"' class='button'>Cote Agora</a>");
};
event.preventDefault();
});
$("#initial-cash").bind("blur", function () {
var price = (accounting.unformat($("#financing_value_vehicles").val(), ",")) || 0;
var initialCash = (accounting.unformat($("#initial-cash").val(), ",")) || 0;
var finance = price - initialCash;
var formattedValue = accounting.formatMoney(finance, "", "2", ".", ",");
$("#amount-finance").val(formattedValue);
});
/** ------------ **/
/** BID CALCULATOR **/
$("input#calculate-bid").click(function(event){
var price = (accounting.unformat($("#bid-product-value").val(), ",")) || 0;
var rate = (accounting.unformat($("#bid-tax").val(), ",") / 100) || 0;
var initialCash = (accounting.unformat($("#bid-initial-cash").val(), ",")) || 0;
var value = (accounting.unformat($("#bid-amount-finance").val(), ",")) || 0;
var finance = price - initialCash;
var months = (accounting.unformat($("#bid-prize_parcela").val(), ",")) || 0;
var tax = parseFloat(rate);
var nominator = (Math.pow(1 + tax, months));
var denominator = ((Math.pow(1 + tax, months)) - 1);
var formattedFinance = accounting.formatMoney(finance, "", "2", ".", ",");
$("#bid-amount-finance").val(formattedFinance);
var result = accounting.formatMoney(((finance*nominator*tax/denominator)), "R$ ", "2", ".", ",");
$(".calculator_bid li.result p.value").text(result);
event.preventDefault();
});
$("#bid-initial-cash").bind("blur", function () {
var price = (accounting.unformat($("#bid-product-value").val(), ",")) || 0;
var initialCash = (accounting.unformat($("#bid-initial-cash").val(), ",")) || 0;
var finance = price - initialCash;
var formattedValue = accounting.formatMoney(finance, "", "2", ".", ",");
$("#bid-amount-finance").val(formattedValue);
});
/** ------------ **/
$('.state-active').each(function(i){
active_tab = $(this).attr('href')
$(this).parents('section').find('div' + active_tab).addClass('tab-active')
});
$('.tooltip').hide();
if ($("html").is(".lt-ie9")) {
$('a').hover(
function(){
$(this).siblings('.tooltip').show();
},
function(){
$(this).siblings('.tooltip').hide();
}
);
} else {
$('a').hover(
function(){
$(this).siblings('.tooltip').fadeIn();
},
function(){
$(this).siblings('.tooltip').fadeOut();
}
);
}
tab.live('click', function(event){
event.preventDefault();
link = $(this).attr('href')
el = $(this).parents('.tabs')
el.find('div').removeClass('tab-active');
el.find('a').removeClass('state-active');
$(this).addClass('state-active')
el.find('div' + link).addClass('tab-active');
});
$('a').unbind('click').hasClass('state-active');
$('a.state-active').unbind('click');
$("#schedule nav a").live("click", function(event){
$('#schedule nav a').removeClass('state-active')
$(this).addClass('state-active')
$(".window div").animate({
top: "" + ($(this).hasClass("prev") ? 0 : -210) + "px"
});
event.preventDefault()
});
app.advertisementNewForm();
},
advertisementNewForm: function(){
$('span.select-image').bind('click', function(){
$(this).parent('li').find('input[type="file"]').click();
});
}
});
$().ready(app.init);
}).call(this);
Page load
jQuery load
jQuery plugins
application.js
if ($("#my-tabs").length) {
// tabs code
}
if ($("#my-gallery").length) {
// gallery code
}
if ($("#my-map").length) {
// map code
}
✗
Without a flow control, it’s
difficult separating code
execution per page/need.
Single entry points control the
flow of the application.
Page load
Vendor code
Application modules
sectionInitializer
section
module1 module2 module3 module4
Page load
Vendor code
Application modules
sectionInitializer
section
module1 module2 module3 module4
<body data-section='profile'>
define('myapp.core.sectionInitializer', function() {
var section = document.querySelector('body').dataset.section;
require('myapp.section.' + section);
});
// No logic, only modules bootstrapping
define('myapp.section.profile',
[
'myapp.components.photoGallery',
'myapp.components.activityFeed',
'myapp.ui.Tabs'
], function(photoGallery, activityFeed, Tabs) {
photoGallery.init($('[data-user-photo-gallery]'));
activityFeed.init($('[data-user-activity-feed]'));
new Tabs($('[data-user-section-tabs]'));
new Tabs($(‘[data-user-report-type-tabs]'));
});
Those initializers contain no
logic, they only init modules.
Self-registered Modules
Page load
Vendor code
Application modules
moduleInitializer
module1 module2 module3 module4
module3 HTML
module4 HTML
module1 HTML
module2 HTML
<div data-module="photoGallery">
<!-- gallery markup -->
</div>
<div data-module="wishlistMap">
<!-- map markup -->
</div>
// moduleInitializer
$("[data-module]").each(function () {
var module = $(this).data("module");
require("myapp.modules." + module).init(this);
});
Each module
“initializes itself”.
Action/section free,
global use.
EVENTS
Observer Pattern
Modular and Event-Driven JavaScript
Observable (server)
“When a new episode is
available, I’ll notify all pirat—I
mean—clients."
Observer (client/pirate)
“Whenever the server notifies
me about a new episode, I’ll
download it.”
OBSERVER OBSERVABLE
Yo, can you give me a
shout out whenever a new
GoT episode comes out?
Sure, my good sire!
YO
"THE RAINS OF
CASTAMERE" IS OUT GET
IT WHILE IT’S HOT
Cool, then I’ll download
it! It’ll surely by a very
happy episode <3
// Pirate observes torrent server
torrentServer.on("new-got-episode", function (name) {
this.download(name);
});
// Torrent server publishes that it has a new GoT episode
this.trigger("new-got-episode", "The Rains of Castamere");
Mediator
Facilitates the
communication
between modules.
Modular and Event-Driven JavaScript
MEDIATOR
All modules have no
knowledge about each other,
except for the Mediator.
MEDIATOR
Mediator, please tell me
when a new The Walking
Dead episode comes out
Sure thing
MEDIATOR
Mediator, please tell me
when a new Mythbusters
episode comes out
Groovy.
Hey, I’ll want that
as well!
Jammin'.
MEDIATOR
Mediator, there’s a new
The Walking Dead episode!
Here’s the link!
Yo folks, there’s a new
The Walking Dead
episode! Here’s the link!
Oh yeah, I’ll get it
right now!
MEDIATOR
Mediator, there’s a new
Mythbusters episode!
Here’s the link!
Yo everyone, there’s a
new Mythbusters
episode! Here’s the link!
Cool, I’ll download
it!
Tnx yo!
// Pirate 1 subscribes to mediator
mediator.on("new-twd-episode", function (data) {
console.log("Downloading " + data.name + " from " + data.link);
});
mediator.on("new-mythbusters-episode", function (data) {
console.log("Downloading " + data.name + " from " + data.link);
});
// Pirate 2 subscribes to mediator
mediator.on("new-mythbusters-episode", function (data) {
console.log("Downloading " + data.name + " from " + data.link);
});
// Torrent server 1 publishes on mediator
mediator.trigger("new-twd-episode", {
link : "http://foo.bar",
name : "The Suicide King"
});
// Torrent server 2 publishes on mediator
mediator.trigger("new-mythbusters-episode", {
link : "http://theillegalbay.br",
name : "Hollywood Myths"
});
Everyone knows only
the Mediator.
jQuery
MyApp.mediator = $({});
Mixin
Modular and Event-Driven JavaScript
// MyApp.myModule now has the `on`, `off` and `trigger` methods
$.extend(MyApp.myModule, EventEmitter.prototype);
MyApp.components.myModule.trigger("my-event", "my-data");
GETTING REAL
AMD
vs.
CommonJS
vs.
Plain Objects
vs.
ES6
How does your
product work?
Synchronous or
asynchronous?
Do you have a
build process?
Will you use client-side
code on the server-side?
Are you feeling lucky?
Events
vs.
Promises
vs.
Dependency Injection
vs.
ES6
¯_(ツ)_/¯
In the end, there’s no
unique solution.
Choose whatever makes
you and your team more
comfortable.
If you do it right,
JavaScript can be fun.
Modular and Event-Driven JavaScript
Modular and Event-Driven JavaScript
Modular and Event-Driven JavaScript
THANKS!slideshare.net/eshiota
github.com/eshiota
@shiota

More Related Content

PDF
Arquitetura de Front-end em Aplicações de Larga Escala
PDF
Responsive Web Design e a Ubiquidade da Web
PDF
Angular JS blog tutorial
PPT
Creating the interfaces of the future with the APIs of today
PDF
Sane Async Patterns
PPT
Ionic tabs template explained
PDF
DrupalCon jQuery
PDF
jQuery: Events, Animation, Ajax
Arquitetura de Front-end em Aplicações de Larga Escala
Responsive Web Design e a Ubiquidade da Web
Angular JS blog tutorial
Creating the interfaces of the future with the APIs of today
Sane Async Patterns
Ionic tabs template explained
DrupalCon jQuery
jQuery: Events, Animation, Ajax

What's hot (20)

PDF
Enjoy the vue.js
PDF
Intro to Ember.js
PDF
Dependency Management with RequireJS
PDF
An introduction to Ember.js
PPTX
Intro to Ember.JS 2016
PPTX
IndexedDB - Querying and Performance
KEY
Jarv.us Showcase — SenchaCon 2011
PDF
Survey of Front End Topics in Rails
PDF
Image Manipulation in WordPress 3.5 - WordCamp Phoenix 2013
PDF
前端MVC 豆瓣说
PDF
JavaScript for Flex Devs
PDF
[FEConf Korea 2017]Angular 컴포넌트 대화법
PPTX
AngularJS Directives
PPTX
AngularJS Internal
PPTX
Magento Live Australia 2016: Request Flow
PPTX
Building a dashboard using AngularJS
PDF
iPhone Appleless Apps
PDF
Laravel 로 배우는 서버사이드 #5
PPT
Jquery ui
PPT
Building Robust jQuery Plugins
Enjoy the vue.js
Intro to Ember.js
Dependency Management with RequireJS
An introduction to Ember.js
Intro to Ember.JS 2016
IndexedDB - Querying and Performance
Jarv.us Showcase — SenchaCon 2011
Survey of Front End Topics in Rails
Image Manipulation in WordPress 3.5 - WordCamp Phoenix 2013
前端MVC 豆瓣说
JavaScript for Flex Devs
[FEConf Korea 2017]Angular 컴포넌트 대화법
AngularJS Directives
AngularJS Internal
Magento Live Australia 2016: Request Flow
Building a dashboard using AngularJS
iPhone Appleless Apps
Laravel 로 배우는 서버사이드 #5
Jquery ui
Building Robust jQuery Plugins
Ad

Similar to Modular and Event-Driven JavaScript (20)

PDF
The Beauty of Java Script
PDF
The Beauty Of Java Script V5a
PDF
Introduction to JavaScript design patterns
PDF
IOC + Javascript
PDF
HTML5 for the Silverlight Guy
PDF
Responsible JavaScript
PPTX
jquery summit presentation for large scale javascript applications
PDF
Design patterns in javascript
PDF
jQquerysummit - Large-scale JavaScript Application Architecture
PDF
Architecting non-trivial browser applications (Jazoon 2012)
PDF
Heroku pop-behind-the-sense
PPTX
JS Essence
PDF
Building a JavaScript Library
KEY
JavaScript Growing Up
PDF
Modular JavaScript
PDF
JS Single-Page Web App Essentials
PDF
Rp 6 session 2 naresh bhatia
PPTX
The Many Ways to Build Modular JavaScript
ODP
Javascript Update May 2013
PDF
Scalable JavaScript Application Architecture
The Beauty of Java Script
The Beauty Of Java Script V5a
Introduction to JavaScript design patterns
IOC + Javascript
HTML5 for the Silverlight Guy
Responsible JavaScript
jquery summit presentation for large scale javascript applications
Design patterns in javascript
jQquerysummit - Large-scale JavaScript Application Architecture
Architecting non-trivial browser applications (Jazoon 2012)
Heroku pop-behind-the-sense
JS Essence
Building a JavaScript Library
JavaScript Growing Up
Modular JavaScript
JS Single-Page Web App Essentials
Rp 6 session 2 naresh bhatia
The Many Ways to Build Modular JavaScript
Javascript Update May 2013
Scalable JavaScript Application Architecture
Ad

More from Eduardo Shiota Yasuda (12)

PDF
Front-end Culture @ Booking.com
PDF
The anatomy of an A/B Test - JSConf Colombia Workshop
PDF
Dominating the Web Typography
PDF
Internationalisation: 2200+ different ways to view a website
PDF
Web Audio Band - Playing with a band in your browser
PDF
RetroJS - Escrevendo músicas da era 8-bits com JavaScript e Web Audio API
PDF
Criando uma arquitetura de front-end do zero
PDF
Baby.com.br: Analisando, adaptando e melhorando a arquitetura da informação e...
PDF
Desafios do Desenvolvimento de Front-end em um e-commerce
PDF
User Experience para Developers
PDF
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
PDF
O Design e a Interface no mundo da Programação
Front-end Culture @ Booking.com
The anatomy of an A/B Test - JSConf Colombia Workshop
Dominating the Web Typography
Internationalisation: 2200+ different ways to view a website
Web Audio Band - Playing with a band in your browser
RetroJS - Escrevendo músicas da era 8-bits com JavaScript e Web Audio API
Criando uma arquitetura de front-end do zero
Baby.com.br: Analisando, adaptando e melhorando a arquitetura da informação e...
Desafios do Desenvolvimento de Front-end em um e-commerce
User Experience para Developers
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
O Design e a Interface no mundo da Programação

Recently uploaded (20)

PPTX
CroxyProxy Instagram Access id login.pptx
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
PDF
KodekX | Application Modernization Development
PDF
Sensors and Actuators in IoT Systems using pdf
PDF
GamePlan Trading System Review: Professional Trader's Honest Take
PDF
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
PDF
ai-archetype-understanding-the-personality-of-agentic-ai.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
AI And Its Effect On The Evolving IT Sector In Australia - Elevate
PDF
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
PDF
HCSP-Presales-Campus Network Planning and Design V1.0 Training Material-Witho...
PPTX
How to Build Crypto Derivative Exchanges from Scratch.pptx
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Top Generative AI Tools for Patent Drafting in 2025.pdf
PDF
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
PPTX
ABU RAUP TUGAS TIK kelas 8 hjhgjhgg.pptx
PDF
DevOps & Developer Experience Summer BBQ
CroxyProxy Instagram Access id login.pptx
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
KodekX | Application Modernization Development
Sensors and Actuators in IoT Systems using pdf
GamePlan Trading System Review: Professional Trader's Honest Take
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
ai-archetype-understanding-the-personality-of-agentic-ai.pdf
NewMind AI Weekly Chronicles - August'25 Week I
AI And Its Effect On The Evolving IT Sector In Australia - Elevate
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
HCSP-Presales-Campus Network Planning and Design V1.0 Training Material-Witho...
How to Build Crypto Derivative Exchanges from Scratch.pptx
Chapter 3 Spatial Domain Image Processing.pdf
Top Generative AI Tools for Patent Drafting in 2025.pdf
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
ABU RAUP TUGAS TIK kelas 8 hjhgjhgg.pptx
DevOps & Developer Experience Summer BBQ

Modular and Event-Driven JavaScript