
Compartilhar:
Karl é um Developer Advocate da Vonage, com foco na manutenção de nossos SDKs de servidor em Ruby e na melhoria da experiência dos desenvolvedores da nossa comunidade. Ele adora aprender, criar coisas, compartilhar conhecimento e tudo o que esteja relacionado à tecnologia da web em geral.
Ano Novo, Rails Novo
Tempo de leitura: 7 minutos
O início de um novo ano costuma ser visto como o momento ideal para se reinventar self. Fazer aquela matrícula na academia, comer de forma mais saudável, aprender um novo idioma e assim por diante. Nunca fui muito fã dessas resoluções do tipo “ano novo, vida nova”, mas, com base nas primeiras impressões, sou certamente fã do “ano novo, Rails novo”.
Tudo bem, essa parte do “ano novo” não é totalmente precisa; O Rails 7.0 foi lançado no final do ano passado, em 15 de dezembro. Já tivemos uma atualização de patch para oferecer suporte ao Ruby 3.1. A parte sobre o “novo Rails”, porém, parece correta. Uma grande atualização de versão sempre traz uma sensação de novidade, mas o Rails 7.0 vai além disso. Parece uma mudança ousada e empolgante em relação às versões anteriores.
Nos primeiros anos do Rails, sua adoção do princípio “convenção em vez de configuração” e das configurações padrão definidas de forma categórica em termos de ferramentas e componentes era considerada um tanto controversa. Esses princípios fundamentais da abordagem do Rails, que acabaram por fazer parte da “Doutrina do Rails”, foram também o que atraiu muitos desenvolvedores para a estrutura. É claro que era preciso se acostumar com as configurações padrão e aprender as convenções, mas, uma vez feito isso, era simplesmente um prazer trabalhar com o Rails. Essa abordagem geral sustentava o primeiro pilar da Doutrina do Rails: Otimizar para a satisfação do programador.
Um dos pontos fortes do Rails como framework tem sido sua capacidade de evoluir junto com o cenário tecnológico em constante mudança. Nos últimos anos, grande parte dessa mudança ocorreu no front-end, onde o desejo por interfaces reativas levou ao surgimento das Aplicações de Página Única (SPAs) e à consequente mudança na lógica das aplicações, afastando-a do servidor e direcionando-a para o cliente. Um dos impactos dessa mudança foi aumentar a complexidade do processo de desenvolvimento front-end em termos de gerenciamento de dependências, transpilagem, agrupamento de recursos e assim por diante. Desde o Rails 5.2, a solução para gerenciar essa complexidade do front-end tem sido Webpacker.
O Webpacker traz alegria?
Embora o Webpacker tenha simplificado parte da complexidade do gerenciamento de dependências e configurações do front-end, ele sempre pareceu mais uma espécie de solução alternativa, ainda que necessária. Era uma maneira de integrar um aplicativo Rails ao ecossistema de front-end já existente, em vez de uma solução de front-end integrada. Ótimo quando tudo funcionava, mas ainda assim você podia acabar tendo que lidar com alguns problemas complexos de dependências de pacotes do Node ou depurar vários erros de compilação — provavelmente não o tipo de coisa com a qual a maioria dos desenvolvedores Rails quer gastar muito tempo.
Parece que a equipe do Rails adotou a abordagem de Marie Kondo em relação ao Webpacker, pois, no Rails 7, ele não está mais presente. A razão por trás dessa mudança baseia-se nos avanços recentes no ambiente mais amplo da web e da internet, nomeadamente o suporte agora universal dos navegadores ao ES6, combinado com a ampla adoção do HTTP/2. O primeiro elimina a necessidade de transpilagem do código ES6 para ES5, e os recursos de multiplexação do segundo atenuam o impacto na latência causado pela solicitação de vários arquivos pequenos em vez de um único “pacote” grande e agrupado.
Então, você deve estar pensando: “Mas eu ainda preciso de todos os meus pacotes do Node, como faço para obtê-los?”. A resposta para isso é import maps, combinado com CDNs que suportam módulos ES, como o Skypack ou JSPM. Essa combinação elimina a necessidade de ferramentas de compilação ou mesmo de ter o Node instalado localmente. O importmap-rails gem, incluída por padrão no Rails 7, basicamente mapeia “especificadores de módulo simples” para uma fonte de onde esse módulo será carregado. Você define a configuração do seu importmap em um config/importmap.rb arquivo. Os módulos específicos são solicitados em tempo de execução, conforme e quando necessário, por layouts específicos por meio de uma <script> tag do tipo "importmap" no <head> desse layout. Muito legal!
Essa abordagem não vai funcionar para todo mundo. Alguns desenvolvedores vão querer usar o React com JSX ou o TypeScript e, por isso, ainda precisarão de uma etapa de compilação/transpilagem e da capacidade de se integrar ao ecossistema do Node. Bem, ainda é possível fazer isso no Rails 7. O jsbundling-rails gem permite que você use o esbuild, o rollup.js ou o Webpack para agrupar seu JavaScript e, em seguida, distribuí-lo por meio do pipeline de ativos do Rails.
Embora alguns desenvolvedores ainda queiram usar esse tipo de abordagem separada entre front-end e back-end, a mensagem do Rails 7 é que, para a maioria dos casos de uso, não é necessariamente preciso recorrer a algum framework de front-end pesado ou a muito JavaScript personalizado no front-end para proporcionar uma experiência reativa ao usuário no navegador. É possível proporcionar essa experiência usando uma arquitetura de aplicativo muito mais unificada, por meio do Hotwire.
O Hotwire tem um estilo Rails
O Hotwire não é totalmente novo — já podia ser usado no Rails 6 com algumas configurações —, mas agora é a abordagem padrão no Rails 7. O Hotwire, desenvolvido pelas equipes da Basecamp e da Hey, é composto por três bibliotecas: Turbo, Stimulus e a Strada, que ainda não foi lançada.
Turbo
O Turbo faz a maior parte do trabalho pesado. Ele utiliza a renderização do lado do servidor (SSR) para enviar HTML pela rede em vez de JSON, eliminando assim a necessidade de renderização, gerenciamento de estado e assim por diante no front-end. O Turbo combina vários conceitos e técnicas complementares.
Drive: Intercepta cliques em links e envios de formulários, emite uma
fetchsolicitação pelo novo conteúdo e renderiza a resposta em HTML.Frames: Permitem dividir uma visualização em partes ou componentes individuais, de modo que os cliques em links ou o envio de formulários atualizem apenas partes específicas da página da web, em vez de recarregar a página inteira.
Streams: Realiza atualizações parciais da página em resposta a ações assíncronas enviadas por WebSocket ou por um Server-Sent Event.
Tudo isso pode parecer uma funcionalidade bastante comum em um SPA. A principal diferença do Turbo é que a lógica por trás de toda essa capacidade de resposta do front-end não está sendo separada em um framework independente acoplado à parte frontal do seu aplicativo Rails. Em vez disso, ela está bem ali nos seus modelos, visões e controladores do Rails, utilizando convenções claras, lógicas e elegantes.
Este artigo não pretende ser um tutorial, por isso não vou entrar em detalhes sobre essas convenções aqui, mas não deixe de conferir o Manual do Turbo Handbook e referência para desenvolvedores, bem como o página README para a implementação do Turbo no Rails, turbo-rails.
Estímulo
O Stimulus se autodefine como uma “estrutura de JavaScript com ambições modestas” e tem como objetivo complementar o Turbo. Ele se baseia fortemente nos atributos de dados do HTML, utilizando objetos JavaScript chamados controladores para responder a eventos do navegador disparados por elementos com um data-controller ou mapeando ações específicas para eventos do DOM por meio de data-action atributos. Mais uma vez, não vou me aprofundar nos detalhes aqui, mas você pode saber mais no Manual, na referência para desenvolvedorese no página README para a implementação do Stimulus no Rails stimulus-rails.
O Hotwire foi projetado para ser independente de frameworks. Mas faz muito sentido no contexto do Rails, especialmente considerando a forma como as implementações das bibliotecas no Rails se integram com ActiveRecord. Por exemplo, você pode usar um broadcasts_to helper em seus modelos para configurar vários callbacks que publicam em um canal específico, digamos :todo_list, quando qualquer alteração de dados for feita no contexto desse modelo (ou seja, por meio das ações create, update ou destroy).
class Todo < ApplicationRecord
broadcasts_to :todo_list
end
Você pode, então, configurar elementos do Turbo Stream para se inscrever na :todo_list transmissão. Esses elementos são atualizados adequadamente quando ocorrem alterações nos dados. Qualquer pessoa que estiver visualizando uma página que contenha um elemento de stream inscrito nessa transmissão específica verá seu navegador atualizar esse elemento da página em tempo real.
Essa funcionalidade utiliza ActionCable, que há muito tempo faz parte do Rails, em segundo plano. O que turbo-rails faz é conectar tudo de maneira lógica e acessível.
O que mais me impressiona no Hotwire é que ele tem aquele “estilo Rails”. Ele simplifica boa parte da complexidade do front-end por meio de uma abordagem inovadora e de algumas convenções sólidas. Essa sempre foi a filosofia do Rails, e sua integração ao Rails 7 parece seguir muito mais de perto a doutrina do Rails do que o compromisso do Webpacker jamais poderia.
Outros destaques
Embora a mudança que mais chamou a atenção no Rails 7 seja a nova abordagem padrão para trabalhar com o front-end, também há algumas mudanças notáveis no que diz respeito ao back-end. As mais interessantes delas dizem respeito a vários aspectos do trabalho com dados.
A criptografia de registros ativos oferece uma camada extra de segurança ao adicionar atributos criptografados a
ActiveRecord.O carregamento paralelo de consultas proporciona melhorias de desempenho em situações em que as ações do seu controlador precisam carregar várias consultas não relacionadas simultaneamente.
Pessoalmente, estou super animado com o Rails 7 e ansioso para criar algumas coisas legais este ano usando o Rails 7 e as APIs da Vonage. Adoraria saber o que você acha do Rails 7! Me conte lá no Twitter.
Compartilhar:
Karl é um Developer Advocate da Vonage, com foco na manutenção de nossos SDKs de servidor em Ruby e na melhoria da experiência dos desenvolvedores da nossa comunidade. Ele adora aprender, criar coisas, compartilhar conhecimento e tudo o que esteja relacionado à tecnologia da web em geral.