Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Web Development
Code

Componentizando a Web

by
Difficulty:BeginnerLength:LongLanguages:

Portuguese (Português) translation by Erick Patrick (you can also view the original English article)

Essa é uma história sobre um dos meus projetos. Um bem grande. Uma mistura entre PHP e Node.js. É uma aplicação de página única (SPA) por um lado, e um site otimizado para buscas (SEO) de outro. Milhares de linhas JavaScipt, CSS e HTML escritos. Em uma única palavra, um pesadelo em forma de código spaghetti para qualquer desenvolvedor. Houve altos e baixos. Produzindo e solucionando problemas. Lutando com as mais novas tecnologias, acabamos com uma biblioteca simples e maravilhosa, que será o tópico desse artigo.

O Começo

Como sempre acontece, o projeto não foi considerado grande. Recebemos o resumo do encontro com o cliente, discutimos sobre como o desenvolvimento seria levado, que tecnologias seriam utilizadas e como as utilizaríamos. Criamos um grande plano e colocamos para funcionar. No começo, tínhamos algumas poucas páginas, que eram controladas por um CMS. Não tinha muito código JavaScript porque nosso sistema entregava grande parte do conteúdo.

Eis uma versão grosseira de como era a estrutura do nosso projeto:

Colocamos o código que ficaria do lado do cliente em diretórios diferentes. O código do lado servidor era só em PHP, naquele momento, então, ele foi para no diretóriophp. Tudo envolvia cerca de 30 arquivos e estava tudo certo.

A Jornada

Por alguns meses, tentamos alguns conceitos e mudamos os códigos do projeto várias vezes. Comparado ao que temos agora, poderia apontar quatro grande problemas pelos quais passamos.

Problema #1 - Inúmeros Arquivos Mal Estruturados

Parece que o cliente estava feliz com o resultado e decidiu investir um pouco mais em sua presença na Internet. Pediram para criarmos alguns novos recursos. Alguns eram somente novos lugares para conteúdo, outros eram adições a páginas existentes. Nós começamos a adicionar mais e mais arquivos em todos os diretórios listados mais acima. Isso começou a ficar um pouco bagunçado, por isso decidimos criar subdiretórios para as diferentes páginas e salvar o código necessário por lá.

Por exemplo, as folhas de estilo CSS para a página about estavam em css/about/styles.css. O JavaScript estava em js/about/scripts.js e por aí vai. Nós usamos um script PHP que concatena os arquivos. Houve, claro, partes do site que estavam em diversas páginas. Elas eram colocadas no diretório common. Isso deu certo por um tempo, mas não por muito tempo. Quando os diretórios ficaram cheios, demorava muito modificar algo. Você teria de pesquisar em três diretórios diferentes para encontrar algo que era preciso. O site ainda era escrito, principalmente, em PHP.

Problema #2 - A Reviravolta ou Como Nós Bagunçamos Tudo

Naquela época, as aplicações móveis começaram a ficar populares. O cliente queria que seu site também estivesse disponível para dispositivos móveis e essa é a grande reviravolta do projeto. Tivemos de converter o site para uma aplicação de página única. E não foi só isso, era preciso várias e várias funcionalidades em tempo real. Claro, nem todo o conteúdo do site tinha de ser carregado dinâmicamente. SEO ainda era uma parte importante na visão do cliente. Nós escolhemos o conjunto MEAN para as partes futuras. O problema estava na páginas antigas. O conteúdo delas tinha de ser servido pelo PHP, mas a lógica mudou completamente, ao ponto de ser, totalmente, em JavaScript. Por semanas, sentimo-nos como os passageiros do Titanic. Estávamos aperreados para lançar algo, mas encontrávamos buraco atrás de buraco e, logo o nosso navio estaria cheio de água (defeitos/bugs).

Problema #3 - Um Árduo Processo de Trabalho

Nós usamos o GruntJS por um tempo, mas migramos para o Gulp. Isso ajudou bastante, porque aumentou nossa velocidade de desenvolvimento. Porém, ainda era estranho demais para adicionar ou editar componentes existentes. A arquitetura sólida que tínhamos no começo, transformou-se em uma mistura complexa de arquivos. Sim, havia convenções estritas de nomeação e localização dos arquivos, mas ainda assim era bagunçado. Por fim, colocamos nossos cérebros para funcionar e chegamos ao seguinte formato:

Nós dividimos o site em componentes diferentes, que eram quase como caixas pretas. Eles viviam em seus próprios diretórios. Tudo relacionado ao componente era salvo no diretório do componente. Nós projetamos, cuidadosamente, as APIs das classes. Elas eram testáveis e comunicativas. Percebemos que esse tipo de arquitetura funcionava melhor para nós, uma vez que tínhamos inúmeros módulos independentes. Sim, estávamos misturando nossos arquivos JavaScript com os estilos CSS e modelos HTML, mas era mais fácil trabalhar em relação ao módulo que ter de navegar por vários níveis de diversos diretórios.

Problema #4 - Angular vs. Código Customizado

As páginas que eram velhas, que tínhamos de entregar através do PHP, também estavam repletas de código JavaScript. Contudo, em alguns casos, o Angular.js não lidava muito bem com isso. Tivemos de criar alguns hacks para fazer as coisas funcionarem perfeitamente. Nós acabamos em uma mistura de controladores do Angular e códigos customizados. A boa notícia era que o orçamento do projeto tinha aumentado e pudemos usar nossa própria biblioteca. Dessa vez, eu estava desenvolvendo meu próprio pré-processador CSS. O projeto correu muito, muito rápido. Em pouco tempo, pude portar minha biblioteca de forma que pudesse ser usada no lado do cliente. Ela se transformou em uma pequena biblioteca, linha por linha, que, então, começamos a integrar no projeto.

Por Que Criar Uma Nova Biblioteca?

Você deve estar se perguntando isso. Bem, existem diversas outras bibliotecas que proveem uma vasta gama de capacidades. Sim, isso é verdade, mas... não precisávamos de uma vasta gama de funcionalidades. Precisávamos de coisas específicas e nada mais. Nós já tínhamos aceitado adicionar alguns kilobytes a mais, para adicionar uma biblioteca popular. Esse não era o grande problema

A situação da nossa base de códigos que era o problema. Estávamos focados em construir uma boa arquitetura e todos concordávamos que, algumas vezes, uma solução customizadas servia melhor. O uso da Angular, Ember, Knockout ou Backbone trazem seus benefícios, mas, a verdade é que não há uma biblioteca universal.

Gosto do que o Jeremy Keith disse em sua palestra O poder da simplicidade, que o mais importante ao escolher sua ferramenta é a filosofia da pessoa que criou a ferramenta e se essa filosofia alinha com a sua. Se as ideias da biblioteca não alinham com as suas, logo-logo, você encontrará problemas. A mesma coisa aconteceu conosco. Tentamos usar a Angular e encontramos muitas dificuldades. Éramos capazes de resolver os problemas, mas tínhamos de usar hacks e soluções alternativas complexas.

Também tentamos a Ember, mas também não funcionou, principalmente por ela se basear, fortemente, em seu mecanismo de roteamento. A Backbone foi uma escolha interessante e o mais próximo da nossa visão. Entretanto, quando apresentei a AbsurdJS decidimos utilizá-la.

O Que A AbsurdJS Fez Por Nós

A AbsurdJS começou como um pré-processador CSS, expandiu-se em um pré-processador HTML e foi portado, com sucesso, para uso no lado do cliente. Assim, no começo, usamos ele para compilar JavaScript em HTML ou CSS. Sim, você leu direito: começamos criando nossas folhas de estilo e códigos HTML, em JavaScript (provavelmente, isso soe estranho, mas, por favor, continue lendo). Continuei desenvolvendo a biblioteca e várias outras funcionalidades foram adicionadas.

Dividir e Conquistar

Quando se tem um sistema complexo, com muitas páginas, você não quer resolver problemas grandes. É muito melhor dividir em vários problemas menores e solucioná-los um a um. Decidimos que nossa aplicaçao seria construída a partir de componentes menores, mais ou menos assim:

absurd.component define uma classe. Invocando o método MyComp() cria-se uma nova instância.

Vamos Bater Um Papo

Era preciso um canal de comunicação para todos esses pequenos componentes. O padrão de projeto Observador (Observer Pattern) era perfeito para esse caso. Assim, cada componente é um despachador de eventos.

Também somos capazes de passar dados junto das mensagens. A definição de componentes e sua natureza "ouvinte-despachante" é bem trivial. Resolvi adotar esse conceito baseado nas bibliotecas mais populares, além de parecer natural. Isso também facilitou o uso da AbsurdJS por parte dos meus colegas de trabalho.

Controlando a DOM

Além do código HTML servido pelo PHP, tínhamos elementos DOM criados dinamicamente. Isso significava que precisávamos de acesso aos elementos DOM existentes ou aos novos, que seriam adicionados à página. Por exemplo, digamos que temos o HTML a seguir:

Eis um componente que retorna o título da página:

O método populate é o único método mágico em toda a biblioteca. Ele faz inúmeras coisas, como a compilação de HTML ou CSS, ligação de eventos e coisas do tipo. No exemplo acima, ele percebe que há uma propriedade html e inicializa a variável el que aponta para o elemento DOM. Isso funciona muito bem para nós, já que, uma vez que tivermos aquela referência, seremos capazes de trabalhar com aqueles elementos e seus filhos. Para aqueles componentes que precisassem de elementos criados dinâmicamente, a propriedade html aceita um objeto como parâmetro.

O JSON acima é convertido no mesmo código HTML. Escolhi o formato JSON porque, do ponto de vista do JavaScript, ele é muito mais flexível. Somos capazes de fundir objetos, substituir ou apagar só alguma parte deles. Nas bibliotecas mais populares, os modelos (templates) são em texto puro, o que dificulta sua manipulação. AbsurdJS também tem seu próprio motor de modelagem (templating engine).

O resultado é:

A palavra chave this nas expressões acima, aponta para o próprio componente. O código entre <% e %>é JavaScript válido. Assim, recursos como propriedades computadas podem ser desenvolvidas diretamente na definição do modelo. Claro, somos capazes de usar o mesmo motor de modelagem com código HTMl já existente. Por exemplo:

... poderia ser controlado pelo componente a seguir (o resultado é o mesmo):

De qualquer forma, o ponto é que fomos capazes de definir modelos ou criar novos modelos do zero. Também fomos capazes de controlar os dados que eram injetados de forma simples e natural. Tudo é uma propriedade do bom e velho objeto JavaScript.

E Com Relação À Estilização?

Nós dividimos o sistema inteiro, de forma bem sucedida, em vários módulos pequenos. As partes que, antes, eram controladores Angular, tornaram-se componentes do AbsurdJS. Percebemos que o HTML estava fortemente ligado às suas definições, o que mudava completamente a administração dos códigos HTML na aplicação. Paramos de pensar em concatenção, conveções e qualquer coisa dessas. Não tivemos de criar qualquer arquivo HTML. Quando penso naquele momento, consigo visualizar o ponto exato em nosso histórico de commits. É facilmente visível, porque muitos arquivos foram removidos da nossa base.

Então pensei, o que aconteceria se fizéssemos o mesmo com o CSS? Isso também foi possível, claro, porque a AbsurdJS também era um pré-processador CSS e podia produzir CSS. Só pegamos a cadeia de caracteres compilada, criamos uma nova tag style no head da página atual e o injetamos lá.

Eis a tag style gerada:

E, dia após dia, transferimos as folhas de estilo CSS dos arquivos SASS (porque, em um dado momento, optamos pelo SASS como nosso pré-processador CSS) para componentes AbsurdJS. Sendo honesto, foi muito fácil porque todas as mixins e variáveis que tínhamos, eram funções e variáveis JavaScript. O compartilhamento de estilos foi ainda mais fácil, já que tudo era JavaScript.

Aquele Momento Estranho

... quando tudo funciona perfeitamente mas você sente que algo está errado.

Estávamos olhando o código. Ele funcionava. A AbsurdJS colocou rédeas até nas partes antigas. O novo e o antigo usam a mesma biblioteca. O HTML e o CSS estavam bem separados e posicionados como definições de componentes. Entretanto, sentia que algo estava faltando. Parei por um tempo e perguntei para mim mesmo: "Do que a Web é feita?".

O que nós fizemos, é um pouco diferente. Parece mais com a imagem abaixo.

Construi sites por mais de uma década e lembro das vezes que lutamos pela separação desses três materiais básicos. E, aquilo que fiz nesse projeto, é exatamente o contrário. Praticamente não tinha arquivos CSS e HTML. Tudo era JavaScript. 

Muitas pessoas dirão que é ridículo e que deveríamos devolver o dinheiro do cliente. Verdade, poderíamos fazer isso mesmo, mas o conceito funcionou perfeitamente para o nosso caso. Não criamos uma aplicação. Para dizer a verdade, criamos vários componentes independentes. Acredito que a Web será a combinação de componentes prontos para serem usados

Como desenvolvedores, teremos de desenvolver tais componentes e, provavelmente, conectar e usar componentes criados por outros. Projetos como AbsurdJS ou Polymer mostram que isso é possível e encorajo você a experimentar seguir esse caminho.

De Volta À Realidade

Assim, o negócio do cliente seguiu bem. Saiu-se tão bem, que decidiu lançar outro serviço. E, advinhem. Ele queria algumas partes da aplicação atual sendo usadas no novo serviço. Não consigo mostrar o quão feliz estávamos ao mover componentes de um lugar para outro. Não precisamos preparar nada, copiar arquivos HTML ou CSS. Só pegamos os arquivos JavaScript dos componentes, colocamos em algum lugar e os instanciamos. Simplesmente funcionaram, já que não tinham dependências. Não duvidaria se alguns desses componentes estivessem à venda logo-logo. Eles são bem leves e proveem uma funcionalidade legal e estão conectados ao produto do cliente.

Sim, quebramos algumas regras. Regras que eu, pessoalmente, acredito. Regras que segui por vários anos. Porém, a realidade é que todos queremos qualidade e, algumas vezes, essa qualidade é alcançável quebrando as regras. Queremos produzir código bom, flexível e manutenível. Não queremos olhar para trás e dizer, "Ó deus... fui eu quem escrevi aquilo!?!". Quando eu olho para trás, agora, eu sei o porque do código ser do jeito que é. Ele é daquele jeito porque foi escrito para aquele projeto em específico.

Conclusão

Se achou esse texto interessante, veja a página oficial da AbsurdJS. Há guias, documentação e artigos por lá. Você pode, até, testar a biblioteca on-line. Como qualquer outra ferramenta, a AbsurdJS foi desenvolvida para um uso específico. Ela serve bem para nossos projetos e, talvez, sirva para os seus. Nem a considero uma biblioteca de verdade, porque não gosto da definição da palavra. Ela está mais para uma ferramenta que uma biblioteca completa. Sinta-se livre para experimentá-la, enviar pull requests ou avisar de problemas. Ela é de código aberto e está disponível no GitHub.

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.