Minha opinão sobre Rails 3.1 e suas polêmicas

No meu dia a dia como desenvolvedor eu passo a maior parte do tempo no Frontend. Para falar a verdade meu maior interesse é em ver as telas funcionando perfeitamente e com usuários satisfeitos com a praticidade do que resolver algoritmos e problemas complexos de arquitetura no Backend.
Gosto muito de Rails pois ele me da ferramentas para criar um Backend flexível e de uma forma relativamente simples e poder me dar tempo para dar a devida atenção ao Frontend. Não tenho nenhuma grande queixa sobre desenvolvimento web hoje em dia com Rails no Backend mas ainda acho que Frontend precisa evoluir muito.
Problemas do frontend
Só para citar alguns exemplos, CSS e JS idealmente precisam ser compilados em um único arquivo para reduzir o número requests. Com isso em mente, quais são os melhores Patterns para evitar que o Namespace global dessas duas linguagens fique poluído em um projeto que tem umas 200 telas? Qual é a melhor forma de organizar seus arquivos JS e CSS de forma que qualquer Designer consiga achar as coisas de rapidamente? Como separar um CSS em vários arquivos por razões de manutenção sem elevar o número de Requests? Como crias CSS-Sprites sem perder minutos calculando posições dos elementos?
Esses são apenas uns dos problemas que temos que enfrentar como desenvolvedores de Frontend. Mas para tudo existem soluções (Sprockets, Asset Packager, Frameworks de CSS, SCSS e etc), porém não existe nada que incorpore tudo de uma forma padrão e com convenções claras. Ou seja, se você quer resolver tudo isso de uma forma clara vai terminar criando um framework próprio com dezenas de dependências externas para essas ferramentas que citei.
Eu costumo pensar que em um papel quadriculado é mais difícil cometer erros ao desenhar polígonos. Convenções fazem possuem essa função e do papel quadriculado e no caso de CSS e JS, no sentido de organização e boas práticas, ainda não existe nada muito sólido como o que o Rails já fez com seu Backend (não acho que frameworks de JS e CSS de hoje resolvam isso muito bem).
Nem CSS, HTML ou JS possuem ferramentas necessárias para resolver todos esses problemas sozinhos. Para compilar vários arquivos CSS ou JS, poder fazer requires sem aumentar requests e criar “helpers” para coisas como Sprites o ideal é que exista uma ferramenta no backend que gere tudo e faça cache em produção.
Resolvendo CSS
No caso de CSS eu acredito que esse problema foi resolvido com maestria pelo Sass atual.
Eu pessoalmente sempre fui contra a sintaxe antiga do Sass pois do meu ponto de vista criar uma nova DSL para algo que já funciona bem não é uma solução. CSS, em si, não é uma linguagem ruim mas para resolver os problemas que citei precisamos de um backend para poder processar as coisas e acrescentar algumas features para melhoria de manutenção como helpers, mixins, requires e nesting (alguns exemplos dessas features do SCSS abaixo).
// require/import
@import "shared/global";
// nesting e mixins
h2 {
font-size: 15px;
padding: 10px;
@include border-radius(4px, 4px, 4px, 4px);
@include background-gradient(#5a656b, #404d55);
@include text-shadow(1px 1px 1px #404d55);
a { color: #7EDAFF; }
a:hover { text-decoration: underline; }
.button, .dangerButton, .positiveButton {
position: absolute;
top: 2px;
right: 3px;
}
}
Com a “nova sintaxe”, Sass (SCSS) se tornou um super-set do CSS convencional e acredito que todos esses problemas que citei foram resolvidos sem criar novos (como necessidade de converter CSS de plugins tipo Fancybox).
Ou seja, tudo que você sabe sobre CSS é aplicável, suas ferramentas e editores ainda funcionam sem trabalho extra, código de terceiros ainda funciona sem a necessidade de conversões e você pode tirar proveito de um processador no Backend.
O que falta ainda é uma convenção forte para organização dos arquivos, classes e ids sem bagunçar a ordem de precedência do CSS quando for feita a compilação. No entanto, acredito que esse problema é resolvido se você definir uma convenção e forma de trabalho na sua equipe (futuramente farei um post sobre como fazemos aqui na Objetiva).
Resumindo: Colocar Sass como padrão no Rails, ajuda bastante nos principais problemas que eu tinha com CSS, o que é um grande ganho. Mas ainda temos o problema do Javascript.
Resolvendo Javascript?
Atualmente, para frontend, as duas maiores alternativas que temos é Action Script (encapsulado dentro do FlashPlayer) e Javascript disponível nos browsers.
Ferramentas para comportamento no frontend?
Honestamente não acho AS3 nem JS linguagens fantásticas.
A maioria das pessoas atira pedras em AS3 e Flash sem nunca ter escrito um aplicativo com eles. Tentando ser o mais pragmático possível, podemos levantar as vantagens e desvantagens dessas ferramentas.
Como vantagens no mundo Flash temos os bons patterns e organização sólida forte na comunidade, coisa que em JS ainda está engatinhando e formalizando agora. Por exemplo, em AS3 todo desenvolvedor sabe a diferença entre as fases de Bubble e Capture de eventos e usa isso para criar componentes com baixo acoplamento. Também existem dezenas de frameworks que ajudam muito na separação das camadas no Frontend.
No entanto, eu acho ActionScript uma linguagem burocrática e com um modelo de Orientação a Objetos muito fraco (passei os últimos 4 anos trabalhando com Ruby, uma linguagem com OO puro). ActionScript 3 também não possuí características do paradigma funcional, o que do meu ponto de vista define uma linguagem que não faz nenhum dos dois principais paradigmas de hoje de uma forma muito interessante.
O problema acima junto com tipagem estática, falta da cultura de testes, reflexividade, dinamismo e meta-programação zero tornam a linguagem muito pouco flexível. Também acho péssimo para um linguagem baseada em eventos não ter closures como temos em Ruby ou Javascript. Juntando essas questões com a necessidade de um Plugin de terceiros eu considero Flash uma ferramenta onde sua aplicação perfeita é bem específica (mas encaixa como uma luva em casos como TreinaTOM ).
Na outra ponta temos Javascript. É muito empolgante ver como a comunidade em torno da linguagem está evoluindo e criando ferramentas fenomenais como Raphael.js e Backbone.js. Também é bem legal ver que as pessoas estão começando a se preocupar em entender a linguagem direito. Mas do meu ponto de vista, não quer dizer que só por causa disso a linguagem passou a ser fantástica e genial.
Eu acho importante aprender a separar a sua empolgação de aprender novas coisas com os fatos reais.
Hoje é comum você ver muita gente vestir a camisa do Javascript e dizer que é uma linguagem linda. Eu descordo absolutamente, acho Javascript uma linguagem flexível e poderosa mas esteticamente ruim (mas isso é gosto né).
Em AS3 é normal ter aplicativos com milhares de linhas de código e separado em centenas de arquivos. Com coisas tipo Backbone.js e Sprockets isso é bastante possível em JS mas ainda acho algo bem mais complexo do que manter algo escrito em uma linguagem como Ruby.
Mas do meu ponto de vista JS tem problemas bem chatos. Problemas como seu escopo global junto com ausência de como fazer “require” de arquivos de forma fácil. Também é uma linguagem muito fácil de escrever bizarrices enormes e uma comunidade sem cultura de testes favorece isso (o que parece estar mudando).
Mas também possui pontos fantástico como herança baseada em Prototype, tipagem dinâmica, closures e funções como objetos de primeira classe (que faz muito sentido para Frontend baseado em eventos).
Também acho sua API’s enxuta uma vantagem para algo que roda nativo nos browsers. Outra vantagem que acho essencial sobre AS3 é não ter que inventar nada especial para poder fazer testes de aceitação.
Por essas razões (e por não ter muitas outras opções) Javascript é a minha opção padrão para a maioria das necessidades de aplicativos Web. Com isso meu objetivo tem sido dominar a linguagem e aprender a gostar mais das vantagens do que das desvantagens.
Coffeescript e Sprockets
O que levantei no tópico anterior é apenas opinião pessoal. O único problema que é incontestável em JS com projetos de médio/grande porte é como arquitetar as dezenas de arquivos de uma forma coerente e compilar isso tudo. Para esse problema temos uma ferramenta chamada Sprockets.
Embutir Sprockets no Rails deixa bem mais claro que código JS não é mais apenas um ponto cego no aplicativo mas também código que deve ter qualidade e atenção. Vamos poder, por padrão, organizar JS de uma forma inteligente e tirar proveito de coisas como “requires”, comentários de versão, compilação e re-aproveitamento de assets. Isso e outros benefícios da ferramenta permitem criar uma excelente organização.
Então, atacando o problema de frontend (que é parece ser o objetivo maior do Rails 3.1), adotar Sprockets me parece a melhor alternativa.
Da parte de JS no Rails 3.1 outra coisa que está entrando é Coffeescript como default. Do meu ponto de vista isso pode influenciar vários fatores.
Primeiro, sempre tivemos RJS no Rails. Eu acho bem interessante mas era algo relativamente fraco pois não era possível escrever tudo em RJS. Coffeescript resolve isso perfeitamente e preenche a lacuna do RJS que ficou sobrando hoje no Rails de uma forma bem mais madura.
Um problema que vejo com Coffeescript, é que diferente de SASS, ele não um super-set de JS então você vai precisar adaptar suas ferramentas e também aprender uma nova linguagem. Como Rails é um framework Ruby e Coffee é muito parecido com Ruby eu não vejo isso como um grande problema.
Outro fato é que o uso é opcional, mas sendo algo padrão, a chance de várias pessoas usarem é bem maior. Para pessoas que trabalham como consultores isso é um ponto importante pois vamos precisar dominar essa nova linguagem para saber se virar muito bem ao fazer code-review ou manutenção em um sistema que esteja usando o padrão do Rails.
O último ponto é que se Coffeescript, como linguagem, é algo valido ou não. Na verdade isso só depende de gosto mas eu tento não me fechar para nada que tenha como objetivo escrever código mais expressivo e fácil de manter (testei HAML quatros vezes até decidir que não gosto). Por isso já estou estudando Coffee (e tenho gostado bastante) e a linguagem em si já resolve algumas coisas que acho bem chatas em Javascript puro (como Strings e heredoc que se torna templates em JS algo bem custoso de se manter).
// CoffeeScript
author = "Wittgenstein"
quote = "A picture is a fact. -- #{ author }"
sentence = "#{ 22 / 7 } is a decent approximation of π"
// Javascript
var author, quote, sentence;
author = "Wittgenstein";
quote = "A picture is a fact. -- " + author;
sentence = "" + (22 / 7) + " is a decent approximation of π";
loadrun: sentence
Ainda temos o ponto que Coffee é opcional e se por alguma razão você não se adaptar (como não me adapto com HAML) basta remover. Não vejo razão para toda essa polêmica.
Conclusão
Com isso tudo em mente eu não vejo o acréscimo do Coffeescript como algo absurdo e maléfico.Rails é um framework full stack mas em Frontend ele ainda tem vários problemas não resolvidos. Eu acredito que essas mudanças são passos para termos uma camada de Frontend mais robusta no futuro.
Recebi essas novidades com bons olhos e acho que mesmo engordando um pouco o Framework isso acontece por boas razões. Outro ponto é que decidir se você gosta ou não de Coffeescript é decisão sua e não do Rails então você pode optar por remove-lo mas eu não faria isso antes de testar e aprender a linguagem.