184
Criando uma arquitetura de front-end do zero @shiota 2013

Criando uma arquitetura de front-end do zero

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Criando uma arquitetura de front-end do zero

Criando uma arquitetura de front-end do zero 

@shiota 2013

Page 2: Criando uma arquitetura de front-end do zero

olá!slideshare.net/eshiotagithub.com/eshiota

@shiota

Page 3: Criando uma arquitetura de front-end do zero

front-end engineer@

Page 4: Criando uma arquitetura de front-end do zero

como a Baby (re)nasceu

Page 5: Criando uma arquitetura de front-end do zero

* reprodução pelo WaybackMachine, não é 100% precisa

Page 6: Criando uma arquitetura de front-end do zero

* reprodução do dia 27/08/2013

Page 7: Criando uma arquitetura de front-end do zero

projeto greenfield(a.k.a. o sonho de todo desenvolvedor)

Page 8: Criando uma arquitetura de front-end do zero

como estruturar o front-end do zero?

Page 9: Criando uma arquitetura de front-end do zero

filosofia de um front-end de larga escala

Page 10: Criando uma arquitetura de front-end do zero

Alta performance client-side.

Page 11: Criando uma arquitetura de front-end do zero

Interface facilmente modificável.

Page 12: Criando uma arquitetura de front-end do zero

Componentes portáveis entre diferentes aplicações.

Page 13: Criando uma arquitetura de front-end do zero

Bulletproof web design.

* veja http://simplebits.com/publications/bulletproof/

Page 14: Criando uma arquitetura de front-end do zero

Tipografia e grids flexíveis, responsive-ready.

Page 15: Criando uma arquitetura de front-end do zero

Baixa barreira de entrada para outros desenvolvedores.

Page 16: Criando uma arquitetura de front-end do zero

definição de suporte aos navegadores

Page 17: Criando uma arquitetura de front-end do zero
Page 18: Criando uma arquitetura de front-end do zero
Page 19: Criando uma arquitetura de front-end do zero

latest latest 5+iOS 6+

8+

Page 20: Criando uma arquitetura de front-end do zero

latest latest 5+iOS 6+

8+

u mad?

Page 21: Criando uma arquitetura de front-end do zero

O meu website precisa ter o visual exatamente igual em todos os navegadores?

Page 22: Criando uma arquitetura de front-end do zero
Page 23: Criando uma arquitetura de front-end do zero

O meu website precisa ter exatamente a mesma experiência em todos os navegadores?

Page 24: Criando uma arquitetura de front-end do zero
Page 25: Criando uma arquitetura de front-end do zero

A escolha dos navegadores e o nível de suporte influencia escolhas e tempo de desenvolvimento.

Page 26: Criando uma arquitetura de front-end do zero
Page 27: Criando uma arquitetura de front-end do zero

CSS

Page 28: Criando uma arquitetura de front-end do zero

pre-processors: sass

Page 29: Criando uma arquitetura de front-end do zero

O uso de partials ajuda a organizar os módulos.

Page 30: Criando uma arquitetura de front-end do zero

@import "compass/css3";

@import "base/variables";@import "base/functions";@import "base/mixins";@import "base/helpers";

@import "core/reset";@import "core/basic";@import "core/forms";@import "core/tables";@import "core/typography";@import "core/icons";@import "core/buttons";

@import "layout/main";@import "layout/header";@import "layout/footer";

@import "ui/loader";@import "ui/loaderBar";@import "ui/flashMessage";@import "ui/breadcrumb";

Page 31: Criando uma arquitetura de front-end do zero

app/ assets/ stylesheets/ base/ _functions.scss _mixins.scss _variables.scss ui/ _breadcrumb.scss _carousel.scss _dentedBox.scss _flashMessage.scss

Page 32: Criando uma arquitetura de front-end do zero

Variáveis ajudam a manter os mesmos padrões de interface.

Page 33: Criando uma arquitetura de front-end do zero

/*********************************************************************** Variables Module** All constants that will be used through the styles must be* defined here.**********************************************************************/

/********************************************************************** =Dimensions*********************************************************************/

$SITE_WIDTH: 978px;$FOOTER_HEIGHT : 812px;$DEFAULT_FONT_SIZE : 16px;

/********************************************************************** =Colors*********************************************************************/

$TEXT_COLOR: #555;$LINK_COLOR: #447f87;

$PURPLE: #905194;$LIGHT: #fefefa;$ORANGE: #fbb100;$YELLOW: #fffd7d;

Page 34: Criando uma arquitetura de front-end do zero

Mixins padronizam repetições de código.

Page 35: Criando uma arquitetura de front-end do zero

/********************************************************************** =Image replacement** `display` property may be overridden by the element.*********************************************************************/

@mixin image_replacement { text-indent: 101%; overflow: hidden; white-space: nowrap; display: block;}

Page 36: Criando uma arquitetura de front-end do zero

.my-logo { text-indent: 100%; overflow: hidden; white-space: nowrap; display: block; width: 200px; height: 280px; background: url("mylogo.png");}

.my-other-logo { text-indent: 100%; overflow: hidden; white-space: nowrap; display: block; width: 100px; height: 150px; background: url("myotherlogo.png");}

Page 37: Criando uma arquitetura de front-end do zero

.my-logo { @include image_replacement; width: 200px; height: 280px; background: url("mylogo.png");}

.my-other-logo { @include image_replacement; width: 100px; height: 150px; background: url("myotherlogo.png");}

Page 38: Criando uma arquitetura de front-end do zero

Mixins padronizam repetições de código.

Page 39: Criando uma arquitetura de front-end do zero

/* <div class="section-header my-theme1"> ... </div>*/

.section-header { width: 100%; height: 15em; color: #fff; background-color: #905194; background-position: center center; background-repeat: no-repeat; background-image: url("themes/default_bg.jpg"); text-align: center;}

.my-theme1 { background-color: #fbb100; color: #fff; background-image: url("themes/theme1_bg.jpg");}

.my-theme2 { background-color: #fefefa; color: #333; background-image: url("themes/theme2_bg.jpg");}

Page 40: Criando uma arquitetura de front-end do zero

/* <div class="section-header my-theme1"> ... </div>*/

@mixin header_theme($background_color: #905194, $text_color: #fff, $image: "default_bg.jpg") { background-color: $background_color; color: $text_color; background-image: url("themes/#{$image}");}

Page 41: Criando uma arquitetura de front-end do zero

/* <div class="section-header my-theme1"> ... </div>*/

.section-header { @include header_theme; width: 100%; height: 15em; background-position: center center; background-repeat: no-repeat; text-align: center;}

.my-theme1 { @include header_theme(#fefefa, #333, "theme2_bg.jpg");}

.my-theme2 { @include header_theme(#fefefa, #333, "theme2_bg.jpg");}

Page 42: Criando uma arquitetura de front-end do zero

(use com moderação)

Page 43: Criando uma arquitetura de front-end do zero

Funções aceleram o processo de desenvolvimento.

Page 44: Criando uma arquitetura de front-end do zero

// Returns unitless number@function remove-unit($number) { $unit: unit($number); $one: 1;

@if $unit == "px" { $one: 1px; } @if $unit == "em" { $one: 1em; } @if $unit == "%" { $one: 1%; }

@return $number / $one;}

// Returns flexible value using `target ÷ context` formula.// Returns `em` by default, accepts `%` as format.@function flex($target, $context, $unit: "em") { $size: remove-unit($target) / remove-unit($context);

@if $unit == "em" { @return #{$size}em; } @if $unit == "%" { @return percentage($size); }}

// Alias to `flex` function, using `%` as format.@function perc($target, $context: $DEFAULT_FONT_SIZE) { @return flex($target, $context, "%");}

// Alias to `flex` function, using `em` as format.@function em($target, $context: $DEFAULT_FONT_SIZE) { @return flex($target, $context, "em");}

Page 45: Criando uma arquitetura de front-end do zero

.product-title { font-size: 1.5625em; /* 25px / 16px */}

Page 46: Criando uma arquitetura de front-end do zero

.product-title { font-size: em(25px, 16px);}

Page 47: Criando uma arquitetura de front-end do zero

.product-title { font-size: em(25px);}

Page 48: Criando uma arquitetura de front-end do zero

Sintaxe SCSS: quase não há curva de adaptação para quem já escreve CSS.

Page 49: Criando uma arquitetura de front-end do zero

Extensões podem auxiliar de jeitos inimagináveis.(mais sobre isso daqui a pouco)

Page 50: Criando uma arquitetura de front-end do zero

modularização

Page 51: Criando uma arquitetura de front-end do zero

Front-end deve saber de programação?

Page 52: Criando uma arquitetura de front-end do zero

CSS possui muitas similaridades com princípios de programação.

Page 53: Criando uma arquitetura de front-end do zero

estrutura base (reset, base styles)

grid

padrões

módulos

módulos contextualizados

Page 54: Criando uma arquitetura de front-end do zero

Single Responsability PrincipleMódulos de CSS possuem comportamentos contidos e isolados.

Page 55: Criando uma arquitetura de front-end do zero

/******************************************************************************* UI » Flyout** Flyouts are those UI components that look like tooltip, and* are activated when the user clicks on a link. The flyout window* opens text to the link, like those present on the iPad.** **Usage**** <div class="flyout-container">* <div class="flyout [vertical-position]-[horizontal-position]-flyout">* Flyout content* </div>* </div>******************************************************************************/

.flyout-container { position: relative; z-index: 100; // may be adjusted as needed through a context}

.flyout { @include box-sizing(border-box); background: #f9f9f9; border-radius: 2px; border: 1px solid #d5d5d5; box-shadow: 0 2px 0 rgba(0, 0, 0, .1); display: none; position: absolute;

// tip &:after { content: ""; display: block; width: 40px; height: 22px; background: sprite($icon-sprite, tooltip_top_large_gray) no-repeat; position: absolute; }}

...

Page 56: Criando uma arquitetura de front-end do zero

Open/close PrincipleMódulos de CSS devem poder ser extendidos sem modificar sua definição core.

Page 57: Criando uma arquitetura de front-end do zero

/********************************************************************************* UI > Loader** Animated loader for AJAX requests********************************************************************************/

@mixin loader_sprite_position($xoffset, $yoffset) { background-position: sprite-position($icon-sprite, loader_sprite, $xoffset, $yoffset);}

.loader { width: 25px; height: 25px; display: none;}

.loader b { display: block; width: 25px; height: 25px; background-image: sprite-url($icon-sprite);}

.loader b,

.loader .f1 { @include loader_sprite_position(-10px, -10px); }

.loader .f2 { @include loader_sprite_position(-45px, -10px); }

.loader .f3 { @include loader_sprite_position(-80px, -10px); }

.loader .f4 { @include loader_sprite_position(-115px, -10px); }

.loader .f5 { @include loader_sprite_position(-150px, -10px); }

.loader .f6 { @include loader_sprite_position(-185px, -10px); }

.loader .f7 { @include loader_sprite_position(-220px, -10px); }

.loader .f8 { @include loader_sprite_position(-255px, -10px); }

Page 58: Criando uma arquitetura de front-end do zero
Page 59: Criando uma arquitetura de front-end do zero
Page 60: Criando uma arquitetura de front-end do zero
Page 61: Criando uma arquitetura de front-end do zero

// On ui/_buttons.scss

.bt-wrapper .loader { position: absolute; z-index: 4; right: 20px; top: 50%; margin-top: -9px;}

// On modules/_checkoutAddressForm.scss

.address-form .cep-input .loader { position: absolute; right: -33px; top: em(29px);}

Page 62: Criando uma arquitetura de front-end do zero

Dependency Inversion PrincipleMódulos macro não devem ter seus layouts alterados por módulos micro.

Page 63: Criando uma arquitetura de front-end do zero

.flyout

Page 64: Criando uma arquitetura de front-end do zero

guias de estilo

Page 65: Criando uma arquitetura de front-end do zero

#cheat #wip

Page 66: Criando uma arquitetura de front-end do zero
Page 67: Criando uma arquitetura de front-end do zero

JavaScript

Page 68: Criando uma arquitetura de front-end do zero

qual framework usar?

Page 69: Criando uma arquitetura de front-end do zero
Page 70: Criando uma arquitetura de front-end do zero

Analise qual (ou se) vale a pena.

Page 71: Criando uma arquitetura de front-end do zero

Você precisa de rotas client-side?

Page 72: Criando uma arquitetura de front-end do zero

Você precisa de sincronização e persistência de modelos client-side?

Page 73: Criando uma arquitetura de front-end do zero

Você precisa de uma solução pronta pra fazer bind entre view e dados?

Page 74: Criando uma arquitetura de front-end do zero

Você precisa de uma estrutura pronta e fechada para manter a consistência do código?

Page 75: Criando uma arquitetura de front-end do zero

Às vezes você não precisa de um framework terceiro. =)

Page 76: Criando uma arquitetura de front-end do zero

Talvez tudo o que você precise seja um código consistente e organizado.

Page 77: Criando uma arquitetura de front-end do zero

decisões de arquitetura

Page 78: Criando uma arquitetura de front-end do zero
Page 79: Criando uma arquitetura de front-end do zero

"Mas Shiota, todo mundo falou pra eu abandonar o jQuery!"

Page 80: Criando uma arquitetura de front-end do zero

O jQuery diminui bastante a barreira de entrada e dá agilidade.

Page 81: Criando uma arquitetura de front-end do zero

Analise a necessidade. Pese os benefícios. Pesquise outras soluções.

Page 82: Criando uma arquitetura de front-end do zero

single entry points

Page 83: Criando uma arquitetura de front-end do zero

(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 84: Criando uma arquitetura de front-end do zero

Page load

jQuery load

jQuery plugins

application.js

Page 85: Criando uma arquitetura de front-end do zero

Pontos únicos de entrada controlam o flow da aplicação.

Page 86: Criando uma arquitetura de front-end do zero

Page load

Vendor code

Application modules

application.js

dispatcher.js

beforeCommand controllerCommand actionCommand afterCommand

Page 87: Criando uma arquitetura de front-end do zero

Page load

Vendor code

Application modules

application.js

dispatcher.js

beforeCommand controllerCommand actionCommand afterCommand

Page 88: Criando uma arquitetura de front-end do zero

<body data-dispatcher="<%= dispatcher_label %>">

Page 89: Criando uma arquitetura de front-end do zero

<body data-dispatcher="products#show">

Page 90: Criando uma arquitetura de front-end do zero

dispatcher.js

beforeCommand()

productsControllerCommand()

productsShowCommand()

afterCommand()

products#show

Page 91: Criando uma arquitetura de front-end do zero

Os commands não contêm lógica, apenas inicializam outros módulos.

Page 92: Criando uma arquitetura de front-end do zero

namespaces

Page 93: Criando uma arquitetura de front-end do zero

"JavaScript é zoado! Não tem nem namespaces!"

Page 94: Criando uma arquitetura de front-end do zero

window.MYAPP = { commands : { productsShowCommand : function () { console.log("Execute code from products#show page"); } }};

MYAPP.commands.productsShowCommand();

Page 95: Criando uma arquitetura de front-end do zero

"Mas ficar declarando objetos é um saco, e você pode acabar sobrescrevendo..."

Page 96: Criando uma arquitetura de front-end do zero

;(function (root) { root.ns = function (name, obj, scope) { var parts = name.split(".") , curScope = scope || root , curPart , curObj ;

obj = obj || {};

while (typeof (curPart = parts.shift()) !== "undefined") { curObj = (parts.length > 0) ? ((typeof curScope[curPart] !== "undefined") ? curScope[curPart] : {}) : obj;

curScope[curPart] = curObj;

curScope = curScope[curPart]; }

return curScope; };})(this);

Page 97: Criando uma arquitetura de front-end do zero

ns("MYAPP.commands.productsShowCommand", function () { console.log("Execute code from products#show page");});

// Same as:

window.MYAPP = { commands : { productsShowCommand : function () { console.log("Execute code from products#show page"); } }};

Page 98: Criando uma arquitetura de front-end do zero
Page 99: Criando uma arquitetura de front-end do zero

module.js

Page 100: Criando uma arquitetura de front-end do zero
Page 101: Criando uma arquitetura de front-end do zero

Define namespaces e coloca açúcar sintático na definição de funções construtoras.

Page 102: Criando uma arquitetura de front-end do zero

window.EDEN = window.EDEN || {};EDEN.forms = EDEN.forms || {};

EDEN.forms.AddressForm = function (el) { this.element = $(el); this.init();}

$.extend(EDEN.forms.AddressForm.prototype, {

// Public methods // --------------

// Inits the instance init : function () { // Do something }

});

var shippingAddressForm = new EDEN.forms.AddressForm($("#shipping-address"));

Page 103: Criando uma arquitetura de front-end do zero

Module("EDEN.forms.AddressForm", function (AddressForm) {

AddressForm.fn.initialize = function (el) { this.element = $(el);

// Do form stuff }

});

var shippingAddressForm = Module.run("EDEN.forms.AddressForm", $("#shipping-address"));

// or

var shippingAddressForm = new EDEN.forms.AddressForm($("#shipping-address"));

Page 104: Criando uma arquitetura de front-end do zero

Padroniza a criação de novos módulos.

Page 105: Criando uma arquitetura de front-end do zero

desacoplamento via eventos

Page 106: Criando uma arquitetura de front-end do zero
Page 107: Criando uma arquitetura de front-end do zero
Page 108: Criando uma arquitetura de front-end do zero

MEDIATOR

Page 109: Criando uma arquitetura de front-end do zero

MEDIATOR

Mediator, me avisa quando sair o novo do Game of

Thrones?

Blz

Page 110: Criando uma arquitetura de front-end do zero

MEDIATOR

Mediator, me avisa quando sair o novo do Mythbusters?

É nóish.

Page 111: Criando uma arquitetura de front-end do zero

MEDIATOR

Mediator, saiu um eppy novo de Game of Thrones.

Subscribers, saiu um eppy novo de Game of Thrones!

Ae, vou baixar, acho que vai ser feliz e tal

=D

Page 112: Criando uma arquitetura de front-end do zero

MEDIATOR

Mediator, saiu um eppy novo de Mythbusters.

Subscribers, saiu um eppy novo de Mythbusters!

Ae, vou baixar!

Page 113: Criando uma arquitetura de front-end do zero

Os módulos só conhecem o mediator.

Page 114: Criando uma arquitetura de front-end do zero
Page 115: Criando uma arquitetura de front-end do zero
Page 116: Criando uma arquitetura de front-end do zero
Page 117: Criando uma arquitetura de front-end do zero

testes

Page 118: Criando uma arquitetura de front-end do zero
Page 119: Criando uma arquitetura de front-end do zero

describe("EDEN.ui.Loader", function () { var Loader = EDEN.ui.Loader;

beforeEach(function () { loadFixtures("loader.html"); });

afterEach(function () { $("body").find(".loader").remove(); });

it("accepts instance creation without new operator", function () { var newLoader = Loader();

expect(newLoader).toBeInstanceOf(Loader); });

it("appends the loader to body as a default", function () { var loader = new Loader();

expect($("body").find(".loader").length).toEqual(1); });

it("appends the loader through an argument function", function () { var loader = new Loader(function ($loader) { $("#loader-placeholder").append($loader); });

expect($("#loader-placeholder").find(".loader").length).toEqual(1); });});

Page 120: Criando uma arquitetura de front-end do zero

"Mas se eu escrever teste de JavaScript, eu não entrego o projeto!"

Page 121: Criando uma arquitetura de front-end do zero
Page 122: Criando uma arquitetura de front-end do zero

(e os testes de JavaScript quebram o build do CI.)

Page 123: Criando uma arquitetura de front-end do zero

"Mas pra que teste de JavaScript?"

Page 124: Criando uma arquitetura de front-end do zero

— "Precisamos atualizar o jQuery de 1.4 para 1.10"

Page 125: Criando uma arquitetura de front-end do zero
Page 126: Criando uma arquitetura de front-end do zero
Page 127: Criando uma arquitetura de front-end do zero
Page 128: Criando uma arquitetura de front-end do zero

Testes dão a segurança para atualizações, modificações e substituições.

Page 129: Criando uma arquitetura de front-end do zero

HTML

Page 130: Criando uma arquitetura de front-end do zero

sintaxe: erb

Page 131: Criando uma arquitetura de front-end do zero

<% product.foreach_variant(current_cart) do |variant, size, i| %> <label class="variant"> <input value="<%= size.value %>" name="product_size" type="radio" data-price="<%= variant.price.to_f %>" data-variant-sku="<%= variant.sku %>" class="<%= "disabled" unless variant.has_stock? %>" /> <span class="variant-name"><%= size.value %></span> </label><% end %>

Page 132: Criando uma arquitetura de front-end do zero

Próximo do HTML puro.

Page 133: Criando uma arquitetura de front-end do zero

Todos sabem (ou deveriam saber) escrever HTML puro.

Page 134: Criando uma arquitetura de front-end do zero

Menos uma dependência no projeto.

Page 135: Criando uma arquitetura de front-end do zero

classes semânticas

Page 136: Criando uma arquitetura de front-end do zero

Dica 1: Sigam tudo o que o Diego Eis falou. =)

Page 137: Criando uma arquitetura de front-end do zero

Usem classes que descrevem o conteúdo e não o estilo.

Page 138: Criando uma arquitetura de front-end do zero
Page 139: Criando uma arquitetura de front-end do zero

<div class="column-left"> <!-- Dropdown Categoria --> <!-- Dropdown Marca --></div>

<div class="column-right"> <!-- Product Navigation --> <!-- Products List --></div>

Page 140: Criando uma arquitetura de front-end do zero
Page 141: Criando uma arquitetura de front-end do zero
Page 142: Criando uma arquitetura de front-end do zero

column-left?

column-right?

Page 143: Criando uma arquitetura de front-end do zero

Classes semânticas desacoplam o documento do estilo.

Page 144: Criando uma arquitetura de front-end do zero

<div class="products-search-filters"> <!-- Dropdown Categoria --> <!-- Dropdown Marca --></div>

<div class="products-search-filtered-results"> <!-- Product Navigation --> <!-- Products List --></div>

Page 145: Criando uma arquitetura de front-end do zero

products-search-filters

products-search-filtered-results

Page 146: Criando uma arquitetura de front-end do zero

Maior portabilidade do markup entre diferentes projetos.

Page 147: Criando uma arquitetura de front-end do zero
Page 148: Criando uma arquitetura de front-end do zero

data-attributes

Page 149: Criando uma arquitetura de front-end do zero
Page 150: Criando uma arquitetura de front-end do zero

contentDropdown.js

Page 151: Criando uma arquitetura de front-end do zero

Componentes com mesmo comportamento podem ter estilos diferentes.

Page 152: Criando uma arquitetura de front-end do zero

<div class="size-selector"> <div class="size-selector-header" data-dropdown-header> <!-- some title, could be anything --> </div>

<div class="size-selector-content" data-dropdown-content> <!-- content here --> </div></div>

<div class="filter-selector"> <div class="filter-selector-header" data-dropdown-header> <!-- some title, could be anything --> </div>

<div class="filter-selector-content" data-dropdown-content> <!-- content here --> </div></div>

Page 153: Criando uma arquitetura de front-end do zero

Classes diferentes, estilos diferentes.

Page 154: Criando uma arquitetura de front-end do zero

data-attributes iguais, comportamento igual.

Page 155: Criando uma arquitetura de front-end do zero

// Inits the `ContentDropdown` instance//// * `el`: jQuery selectorinit : function (el) { this.element = $(el); this.content = this.element.byData("dropdown-content"); this.selection = this.element.byData("dropdown-selection");}

Page 156: Criando uma arquitetura de front-end do zero

$.fn.byData = function (dataAttr) { return $(this).find("[data-" + dataAttr + "]");};

Page 157: Criando uma arquitetura de front-end do zero

Comportamento é adicionado através dos data-attributes.

Page 158: Criando uma arquitetura de front-end do zero

dicas adicionais

Page 159: Criando uma arquitetura de front-end do zero

performance client-side

Page 160: Criando uma arquitetura de front-end do zero

Faça sprites. De preferência, de maneira automágica.

Page 161: Criando uma arquitetura de front-end do zero
Page 162: Criando uma arquitetura de front-end do zero

$icon-sprite: sprite-map("icon/*.png", $spacing: 16px, $repeat: no-repeat, $layout: vertical);

Page 163: Criando uma arquitetura de front-end do zero

$icon-sprite: sprite-map("icon/*.png", $spacing: 16px, $repeat: no-repeat, $layout: vertical);

Page 164: Criando uma arquitetura de front-end do zero

/* Compass sprite function receives the map variable and image as arguments */

background: sprite($icon-sprite, arrow_dropdown) no-repeat;

/* Compiled CSS */

background: url(/assets/icon-s5dab8c2901.png) -40px -158px no-repeat;

Page 165: Criando uma arquitetura de front-end do zero

Use inline images para imagens < 1KB que estarão apenas em um lugar do CSS.

Page 166: Criando uma arquitetura de front-end do zero
Page 167: Criando uma arquitetura de front-end do zero

/* Compiled CSS */

background: #f5f3fb url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQCAMAAAAcVM5PAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRF5+TW////////4qZUpQAAAAN0Uk5T//8A18oNQQAAACBJREFUeNpiYGBgAgMGBkYog4mJXAbILAiDkVxzAAIMAEMOAPMId2OWAAAAAElFTkSuQmCC') repeat;

/* Generates a base64 image */

background: #f5f3eb inline-image("bg_dots.png") repeat;

Page 168: Criando uma arquitetura de front-end do zero

Use lazy-load onde fizer sentido.

Page 169: Criando uma arquitetura de front-end do zero
Page 170: Criando uma arquitetura de front-end do zero
Page 171: Criando uma arquitetura de front-end do zero

code standards

Page 172: Criando uma arquitetura de front-end do zero
Page 173: Criando uma arquitetura de front-end do zero

"O código deve parecer que foi escrito pela mesma pessoa, independente de quem o escreveu."

Page 174: Criando uma arquitetura de front-end do zero

Código consistente: maior legibilidade, manutenção mais fácil, evita bikeshedding.

Page 175: Criando uma arquitetura de front-end do zero

build para o deploy

Page 176: Criando uma arquitetura de front-end do zero

Ruby on Rails » Asset Pipeline » ♥

Page 177: Criando uma arquitetura de front-end do zero
Page 178: Criando uma arquitetura de front-end do zero
Page 179: Criando uma arquitetura de front-end do zero

TL;DR

Page 180: Criando uma arquitetura de front-end do zero

Alta performance client-sideInterface facilmente modificávelComponentes portáveis entre diferentes aplicaçõesBulletproof web designTipografia e grids flexíveis, responsive-readyBaixa barreira de entrada para outros desenvolvedores

Page 181: Criando uma arquitetura de front-end do zero

Não saia adicionando códigos de terceiros sem pensar.

Page 182: Criando uma arquitetura de front-end do zero

Front-end deixou de ser coisa de agência e sobrinho.

Page 183: Criando uma arquitetura de front-end do zero
Page 184: Criando uma arquitetura de front-end do zero

obrigado!slideshare.net/eshiotagithub.com/eshiota

@shiota