AngularJS: Os Pontos Fracos
Quando uma tecnologia nova e empolgante aparece, ela nos fascina e faz com que achemos que tudo é possível.
À medida em que vemos nossas expectativas excedidas em algumas áreas, começamos a acreditar que podemos usar uma determinada tecnologia em qualquer lugar com relativa facilidade. Experiências passadas nos mostraram o contrário: que isso é garantia de dor de cabeça! Vou falar sobre minha experiência na equipe da thoughtworks.com ao usar o AngularJS para implementar o tech radar interativo.
Um pouco de contexto
Temos um stack de Ruby, Sinatra e JavaScript simples. Mais informações sobre o stack do projeto podem ser encontradas neste artigo de Andy Robinson, da Thoughtworks. Um dos princípios-guia é que a sustentabilidade de um código-base se atinge minimizando a complexidade acidental. Em função disso, procuramos sempre usar bibliotecas em vez de frameworks. Um exemplo concreto é a escolha do Sinatra e não do Rails, principalmente porque o primeiro, ainda que seja um framework, é muito mais leve que o outro.
O tech radar interativo foi implementado no AngularJS. A escolha do AngularJS abriu um caminho rápido na direção de um produto mínimo viável. Também permitiu a implementação de uma interface mais interativa. O produto final foi uma grande melhora em relação à pagina estática cheia de texto e sem graça de antes.
A história da guerra
O impacto imediato foi no tempo de construção. Inserir o AngularJS aumentou o tempo de teste significativamente. Nosso stack de teste (RSpec, Capybara, PhantomJS) era ótima para o tipo de aplicativo que estávamos desenvolvendo: várias páginas em um servidor Web com interação JavaScrip limitada (mas crescente) dentro de uma página. O AngularJS apresentou um desafio interessante: como testar aplicativos complexos de uma só página com interações JavaScript através das páginas? Inserir uma ferramenta específica do AngularJS, como o Protractor, significaria inserir um stack de teste paralelo à atual. A complexidade de prestar suporte e trabalhar com dois stacks de teste diferentes não parecia valer a pena. Por fim acabamos usando ferramentas que deixaram o nosso stack de teste compatível com o AngularJS (por exemplo, capybara-angular). Isso começou a mostrar as desvantagens de usar o AngularJS: ele não funciona muito bem com ferramentas e bibliotecas que não sejam específicas para AngularJS.
Para a segunda iteração tínhamos mais recursos e bugs para consertar na lista. Quando começamos a rodar as histórias sentimos o fardo da curva de aprendizagem ficar mais pesado. Histórias pequenas duravam dias, e fomos entendendo cada vez mais sobre o AngularJS. Como qualquer framework, ele promove seu próprio ponto de vista peculiar. Para tirar o máximo de um framework você precisa aceitá-lo e usar o jeito dele de fazer as coisas. Frameworks são ótimos para chegar rapidamente a um produto mínimo viável, mas é preciso pagar o preço da sustentabilidade e da evolução a longo prazo.
Trabalhando nisso, repetidamente descobrimos que o único caminho é o caminho do AngularJS. O uso de bibliotecas JS tornou-se muito restrito. Na maioria das vezes só se pode usar uma ferramenta Javascript que seja parte do próprio ecossistema. Por exemplo, uma biblioteca baseada em JQuery não funciona muito bem com páginas construídas no AngularJS. Também descobrimos que tarefas simples no JavaScript tornaram-se difíceis. Um exemplo seria usar os eventos onready/onload do DOM (O AngularJS 'sequestra' esses eventos e eles ficam difíceis de usar). Outro exemplo é que o Google analytics não trabalha diretamente com o AngularJS. Você teria que usar bibliotecas específicas do AngularJS para fazê-lo funcionar (como a angulartics). Além disso, o AngularJS inseriu html no nosso código-base, e vínhamos usando o slim para fins de padronização. Um novo conjunto de ferramentas significava aumentar a complexidade acidental no código-base, dificultando a manutenção e a evolução.
Uma das nossas exigências de negócios é que nosso site esteja disponível para usuários sem JavaScript. Isso significava que teríamos que duplicar quase todo o conteúdo interativo no radar (... quebrando o princípio DRY (do inglês, não repita a si mesmo)). Tudo em uma só tag <noscript> gigante! Outro problema que enfrentamos foi o desempenho abaixo do ideal do AngularJS para otimização de motores de busca. Há soluções para melhorar o desempenho (leia esta pergunta no StackOverflow) mas elas exigem mais trabalho extra.
O futuro
Ao olharmos para o futuro do radar, o próximo da fila é o i18n. Isso significa implementar um mecanismo i18n no JavaScript que duplicaria o atual que temos no Ruby. Considerando a dor de cabeça até agora, percebemos que à medida que os requisitos de negócios se tornam mais e mais complexos, não conseguiremos lidar desenvolvendo em AngularJS. Neste ponto parece que o avanço está em remover o AngularJS e substitur por páginas em Ruby ou no bom e velho JavaScript. Pode parecer uma tarefa enorme, mas um pequeno pico já mostrou que, se usarmos os códigos existentes de JavaScript e html com sabedoria, é um trabalho de poucos dias.
Conclusão
Mesmo presumindo que todos os pequenos problemas que enfrentamos têm soluções mais simples e elegantes, isso não muda o fato de que o AngularJS trouxe muita complexidade acidental sem valer a pena pelos benefícios. Eu assumiria de bom grado o custo de aprender e o usar o AngularJS se fosse desenvolver um aplicativo de uma página no JavaScript, mas pensaria duas vezes antes de usá-lo para qualquer outra coisa.
Mais opiniões
Mais dicas úteis sobre desenvolver aplicativos no Angular JS podem ser encontradas neste artigo da Tania Gonzales, da Thoughtworks. Mais detalhes de uma experiência parecida neste post (veja também a discussão que ele gerou no Hacker News). Opiniões diferentes podem ser lidas aqui e aqui. Tenho muito interesse em saber de outras experiências com o AngularJS. Deixe suas impressões na seção de comentários.
Aviso: As afirmações e opiniões expressas neste artigo são de responsabilidade de quem o assina, e não necessariamente refletem as posições da Thoughtworks.