Uma nova visão do desenvolvimento do Fullstack com a estrutura Ruby on Rails

É possível discutir seriamente o desenvolvimento do fullstack? Se você olhar para estruturas grandes para o front-end e para o back-end, falar sobre o fullstack parecerá duvidoso. Sugiro examinar o termo fullstackdo ponto de vista do Ruby on Rails e os princípios mais simples anteriores de implementar a interatividade em páginas da web clássicas. Apresento a você uma visão geral dos recursos de front-end fornecidos na estrutura do Ruby on Rails ou relacionados a ela.

imagem


O Ruby on Rails é uma estrutura MVC que se concentra no desenvolvimento rápido e presta muita atenção à manutenção da consistência dentro de um projeto (para que ele não seja "de qualquer maneira" "rapidamente"). Ele fornece muitas ferramentas para o desenvolvimento de back-end e front-end. Na direção clássica do fullstack, houve uma omissão momentânea devido à ignorância de seu desenvolvimento e equívocos sobre o atraso dos fundos usados. O objetivo deste artigo é destacar como a abordagem de pilha cheia se desenvolve e quantas possibilidades interessantes diferentes apareceram nela.

Webpacker


O Webpacker é uma jóia que acompanha o Ruby on Rails.

O Webpacker fornece um wrapper sobre o Webpack: comandos para conectar e iniciar configurações para o trabalho. O Webpacker de fato define o padrão para trabalhar com front-end no Ruby on Rails, promove o uso dos mais recentes recursos JavaScript e princípios modernos de trabalho com código (estrutura, modularidade, montagem e muito mais).

O Webpacker define as configurações gerais necessárias para iniciar e a estrutura do aplicativo, o que aumenta a segurança e simplifica o entendimento do projeto por diferentes desenvolvedores. Para o código JavaScript, a pasta app/javascript/com o arquivo principal está alocada app/javascript/packs/application.js.

Arquivos e pastas adicionados pelo Webpacker
config/webpacker.yml
config/webpack/
config/webpack/development.js
config/webpack/environment.js
config/webpack/production.js
config/webpack/test.js
package.json
postcss.config.js
babel.config.js
.browserslistrc
node_modules/
bin/webpack
bin/webpack-dev-server
app/javascript/
app/javascript/packs/
app/javascript/packs/application.js


O Webpacker inicia por padrão durante o processo de criação de um novo aplicativo e executa suas configurações. Você pode criar o aplicativo imediatamente com configurações adicionais para Stimulus, Vue, Typescript ou outro da lista fornecida :

rails new myapp --webpack=stimulus

Ou instale configurações adicionais depois de criar o aplicativo:

bundle exec rails webpacker:install:stimulus

Desenvolva o Frontend com a estrutura Ruby on Rails = use as abordagens de desenvolvimento JavaScript mais atuais. Toda a conveniência de usar os modernos padrões JavaScript estão bem integrados ao Ruby on Rails. As configurações necessárias são fornecidas para trabalhar com o Webpack, o que permite que você se distraia menos com a organização correta do projeto e concentre-se em resolver tarefas populares usando o ambiente familiar.

Turbolinks


Turbolinks é a biblioteca JavaScript que acompanha o Ruby on Rails.

A tarefa prioritária do Turbolinks é facilitar a carga no servidor e reduzir "costuras" ao navegar para URLs de aplicativos. Esse recurso geralmente é comparado ao SPA, pois dá a impressão de uma nova renderização do conteúdo no navegador, em vez de transições simples entre páginas.

Princípio de funcionamento dos turbolinks: para navegar entre as páginas, não alternando para um novo endereço padrão, mas preenchendo uma solicitação para esse endereço "em segundo plano" via ajax, carregando a resposta em JavaScript e substituindo o conteúdo da página por um novo. Esse processo é acompanhado por eventos especiais que permitem adicionar funcionalidade à transição entre as páginas e retornar às páginas anteriores. Por exemplo,
  • para iniciar a transição para um endereço diferente: turbolinks:click, turbolinks:before-visit, turbolinks:visit;
  • ou o processamento de uma solicitação para uma nova página turbolinks:request-start, turbolinks:request-end:;
  • ou no processo de exibição de uma nova página turbolinks:before-render, turbolinks:render, turbolinks:load.

Além disso, o Turbolinks possui uma barra de progresso, armazena em cache o histórico de páginas carregadas e permite especificar elementos de página não atualizados.

Cabo de ação


ActionCable faz parte da estrutura Ruby on Rails. O ActionCable facilita o trabalho com soquetes da web. Para listar os canais no servidor, é fornecida uma pasta app/channels/com os arquivos principais . Para implementar a conexão com esses canais - uma pasta com arquivos e . É melhor se familiarizar com as possibilidades do ActionCable imediatamente, por exemplo. A conexão mais simples aos soquetes da Web com sua ajuda pode ser implementada em apenas algumas etapas.channel.rbconnection.rbapp/javascript/channels/index.jsconsumer.js



  1. Criar arquivo de canal

    app / channels / hello_channel.rb
    # app/channels/hello_channel.rb
    class HelloChannel < ApplicationCable::Channel
      def subscribed
        stream_from "hello_1"
      end
    end
    

  2. Crie uma assinatura para este canal
    app / javascript / channels / hello_channel.js
    // app/javascript/channels/hello_channel.js
    import consumer from "./consumer"
    
    consumer.subscriptions.create({ channel: "HelloChannel" }, {
      received(data) {
        console.log("Data received", data);
        document.body.innerText += `\nHello, ${data.name}!`
      }
    })
    


E a conexão com os soquetes da Web está pronta.

Agora, para verificar, precisamos de uma página simples e uma ação para o envio. Para fazer isso, crie um controlador e adicione seus endereços às rotas

app / controllers / hello_controller.rb
# app/controllers/hello_controller.rb
class HelloController < ApplicationController
  def index
    render :html => "Hello page...", :layout => true
  end

  def new
    ActionCable.server.broadcast("hello_1", name: params[:name])
    head 200
  end
end


config / routes.rb
# config/routes.rb
get "/hello" => "hello#index"
get "/hello/new" => "hello#new"


Iniciamos o aplicativo, vamos para o endereço 127.0.0.1haps000 / hello e abrimos o console do navegador, nele você pode ver o log de mensagens provenientes do servidor via soquetes da web.

Em seguida, enviamos uma solicitação de correspondência de ação:

curl http://127.0.0.1:3000/hello/new?name=World

E observe a página / hello e a saída em seu console.

Ajudantes de formulário e Rails-ujs


Destacam-se alguns recursos não novos, mas bem estabelecidos, da estrutura Ruby on Rails. Entre eles estão os auxiliares de representações e formas. A conveniência inicial dos auxiliares é que eles facilitam a integração da marcação com modelos, configurações e outros componentes de back-end. A vantagem dos auxiliares de formulário em relação à marcação convencional é a capacidade de listar rapidamente os campos do formulário sem entrar nos detalhes de sua ligação aos atributos do modelo - usando auxiliares, o relacionamento entre eles será formado automaticamente. Um fragmento mostrando um exemplo de campos de formulário de ligação com parâmetros do controlador e atributos de modelo:

app / views / articles / new.html.erb
<%# app/views/articles/new.html.erb %>
<%#      %>
<%= form_with(model: Article.new) do |f| %>
  <div>
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>
  <div>
    <%= f.label :text %>
    <%= f.text_area :text %>
  </div>
  <%= f.submit %>
<% end %>


config / locales / ru.yml
# config/locales/ru.yml
#       
ru:
  activerecord:
    attributes:
      article:
        title:  
        text:  


config / application.rb
# config/application.rb
#        config/application.rb
config.i18n.default_locale = :ru


app / controllers / articles_controller.rb
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController

  def new
    #  new   
    # rails -     
  end

  def create
    #        
    @article = Article.create(article_params)

    #    -    ,
    #    url  
    #   ,   
    redirect_to @article
  end

  private

  def article_params
    #      
    params.require(:article).permit(:title, :text)
  end
end


Você pode aprender mais sobre este exemplo aqui e aqui .

Rails-ujs


O Rails-ujs é a parte principal da estrutura do Ruby on Rails para JavaScript discreto.
O Rails-ujs fornece várias opções adicionais para elementos da página que mudam ou expandem a maneira como eles funcionam.

Opção remota - projetada para elementos que acessam o servidor (links, formulários) para fazer solicitações assíncronas. Exemplo de link:

<%= link_to " ", new_article_path, remote: true %>

Para exibir os resultados dessa consulta requer manipulação adicional, por exemplo, adicionar manipulador remoto de eventos: ajax:success, ajax:error, ajax:complete.

A opção de confirmação - permite solicitar a confirmação da ação antes que ela seja executada.

<%= link_to "", article_path(article), method: :delete,
  data: { confirm: ' ,     ?' } %>


Disable_with option - permite desativar um item após uma ação
<%= form.submit data: { disable_with: "..." } %>

Além disso, o Rails-ujs possui vários recursos úteis. Aqui estão alguns deles:

Rails.fire(obj, name, data)- função de chamada de evento
Rails.ajax(options)- wrapper sobre XMLHttpRequest
Rails.isCrossDomain(url)- verificação de URL pertencente a outro domínio
Rails.$(selector)- wrapper sobre document.querySelectorAll Você pode

conectá-los ao seu código com o comando

import Rails from "@rails/ujs"

Estímulo


Estímulo - framework JavaScript dos desenvolvedores Ruby on Rails.

O estímulo é uma das estruturas raras e única à sua maneira, pois implementa o desenvolvimento de front-end usando novas abordagens JavaScript, enquanto não procura controlar todas as suas ações e não impõe uma separação do front-end do back-end.

A tarefa básica do estímulo é vincular manipuladores a eventos. De acordo com o estímulo, o código-fonte deve ser colocado nas classes do controlador e seus métodos devem ser usados ​​como manipuladores. Por padrão, a pasta app/javascript/controllers/com o arquivo primário é alocada para controladores de estímulo no projeto index.js. Aqui podemos adicionar nossos controladores, para isso precisamos criar um arquivo com um sufixo _controller.js, por exemplo,articles_controller.js. Em seguida, o carregador Stimulus importa esses arquivos e conecta os controladores aos blocos correspondentes em nossas páginas.

Os controladores no Stimulus possuem equipamentos adicionais: inicialização do objeto controlador ( initialize), auxiliares para acessar elementos dentro do bloco ( targets, destinos), anexar o objeto controlador ao bloco ( connect) e desconectar-se dele ( disconnect), acessar os atributos de dados do bloco ( this.data.get). A seguir, é apresentado um exemplo de um bloco com estado ativo / inativo escrito em Estímulo.

app / views / home / show.html.erb
<%# app/views/home/show.html.erb %>

<%#   home   %>
<%#      (  ) %>
<div data-controller="home"
    data-home-active-text="Activated" data-home-deactive-text="Deactivated">

  <%#    text  home  %>
  <p data-target="home.text"></p>

  <%#   action click  home %>
  <button data-action="home#click"></button>

</div>



app / javascript / controllers / home_controller.js
// app/javascript/controllers/home_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  //  
  static targets = [ "text" ]

  initialize() {
    //      
    this.activeText = this.data.get("active-text");
    this.deactiveText = this.data.get("deactive-text");
  }

  connect() {
    //   /
    this.active = this.data.get("active") == "true";
    //  
    this.refresh();
  }

  disconnect() {
    //     
    this.element.setAttribute("data-home-active", !!this.active);
  }

  click() {
    //  
    this.active = !this.active;
    //  
    this.refresh();
  }

  //    
  refresh(){
    //     
    this.element.style.background =   this.active ? "none" : "#EEE";
    //  
    this.textTarget.innerHTML =   this.active ? this.activeText : this.deactiveText;
    //   
    this.textTarget.style.color = this.active ? "black" : "#777";
  }
}


Apesar de manter os princípios antigos para implementar a funcionalidade interativa nas páginas clássicas, a abordagem de desenvolvimento com o Stimulus é significativamente aprimorada: a estrutura do código-fonte é estruturada de uma nova maneira, a ligação dos manipuladores aos eventos é alterada e é fornecido equipamento adicional. Graças a essas comodidades e à sua simplicidade, a estrutura Stimulus permite que você estruture de forma rápida e competente até mesmo um grande front-end.

Além disso, vale ressaltar que o Stimulus combina bem com outros recursos do Ruby on Rails - o surgimento útil aparece em quase todos os pacotes.

Estímulo e Webpacker


O Webpacker fornece comandos para criar um aplicativo com um estímulo conectado:

rails new myapp --webpack=stimulus

Ou, para conectá-lo a um projeto já criado:

bundle exec rails webpacker:install:stimulus

Estímulo e JavaScript


O estímulo promove o uso dos modernos princípios de desenvolvimento JavaScript para implementar a interatividade em suas páginas. Com o Stimulus, a solução de front-end é construída de maneira modular, o OOP é usado para manipuladores de eventos e o código é cuidadosamente estruturado. Usando a ferramenta de segmentação, usando controladores de estímulo, é conveniente controlar a conexão com os elementos de bloco de componentes gráficos complexos retirados de bibliotecas de terceiros ou gravados independentemente (calendários, auto-compiladores, listas, árvores e outros). Graças a isso, o Stimulus é uma das maneiras mais simples de mudar as ferramentas de front-end desatualizadas e obter a produtividade necessária com o uso do JavaScript puro e moderno.

Estímulo e Ruby on Rails


Com a estrutura de código recomendada pelo Stimulus, você continua a escrever em JavaScript da mesma forma que faria no Ruby on Rails. Você também declara controladores, também vincula ações a métodos. Com o Stimulus, o desenvolvimento de front-end se torna semelhante ao back-end, o que facilita o trabalho tanto lá quanto ali.

Estímulo e cabo de ação


Usando os métodos de inicialização e conexão em controladores de estímulo, é conveniente vincular os soquetes da Web não à página inteira, mas a seus blocos individuais e trabalhar com precisão com as mensagens recebidas. Está se tornando mais fácil organizar vários fluxos paralelos em uma página com comutação de canal independente.

Estímulo e Turbolinks


O estímulo é ativado assim que o Turbolinks carrega a página; não são necessárias manipulações adicionais para conectar o estímulo aos blocos da página.

Turbolinks não apenas facilita o carregamento de páginas, mas também armazena o conteúdo em cache na transição. Quando você retorna à página em cache a partir do histórico, o Stimulus é ativado automaticamente, como ao carregar uma nova página. Se você deseja salvar alguns valores antes de desconectar o controlador da unidade, pode usar o método disconnect- e, ao retornar e conectar o controlador, ele poderá restaurar seu último estado. No código do primeiro exemplo de trabalho com o Stimulus, você pode ver como, ao desconectar ( disconnect), o valor é fixado no atributo de dados do bloco do controlador this.activee, ao conectar ( connect), é extraído de volta.

O retorno através das páginas pode ser uma maneira útil de trabalhar com o aplicativo. Por exemplo, ao trabalhar com um formulário, pode ser necessário preencher / editar o valor no diretório em outra página, retornar e selecionar novos dados.

Outro exemplo: digamos que precisamos editar ou ver os valores na página de configurações de bate-papo na web. Ao desconectar o controlador da unidade da unidade com a conversa, será útil lembrar o identificador da última mensagem; portanto, ao retornar, solicite primeiro as novas mensagens ausentes e abra a conexão por meio de soquetes da web.

Assim, um retorno no histórico da página pode ser usado como uma maneira conveniente de trabalhar com seu aplicativo da web.

Formulários de estímulo e auxiliares


O estímulo trabalha em estreita colaboração com a marcação e, com a ajuda de auxiliares, os dados são facilmente incorporados em blocos html. Graças a isso, parte dos dados pode ser carregada no atributo de dados do bloco e entregue ao controlador.

app / views / articles / show.html.erb
<%#       app/views/articles/show.html.erb %>

<%#      %>
<% article_data = article.attributes
      .slice("id", "created_at", "updated_at", "author", "title").to_json %>

<%#   div    content_tag %>
<%= content_tag :div,
    :data => { controller: :articles },
    "data-articles-attributes" => article_data do %>
  <%# ... %>
<% end %>


app / javascript / controllers / articles_controller.js (snippet)
//   
//   initialize  app/javascript/controllers/articles_controller.js
initialize() {
  this.attributes = JSON.parse(this.data.get("attributes"));
  //   
  // ...
}


Estímulo e Rails-ujs


Usando o estímulo e as opções remotas, você pode conectar diretamente os controladores aos eventos do ajax e processar os resultados da consulta. Declare o link usando Rails-ujs e anexe um manipulador de estímulos a ele.

link com opção remota e manipulador de estímulos
<%= link_to " ",
  article_path(article, format: :html),
  data: { remote: true, action: "ajax:success->articles#showArticle" } %>


Quando você clica neste link, uma solicitação assíncrona do Ajax para o controlador rails articles_controller.rbpara a ação show ocorrerá . Após o recebimento de uma resposta positiva, um evento será acionado ajax:successe o método showArticledo controlador será chamadoapp/javascript/controllers/articles_controller.js

método showArticle do aplicativo / javascript / controllers / articles_controller.js
showArticle(e) {

  //      
  const xhr = e.detail[2];

  //    
  this.showFormTarget.innerHTML = xhr.responseText;

  //  
  this.showFormTarget.style.display = "block";
}


Qual é o próximo?


Essas ferramentas, juntamente com a estrutura Ruby on Rails, abrem novos horizontes para o desenvolvimento do fullstack. Além disso, as ferramentas descritas são relativamente simples e não exigem mergulhos longos - tudo o que é necessário para um projeto bem-sucedido está à superfície.

Crie aplicativos da Web com ferramentas de desenvolvimento fullstack modernas e rápidas com a estrutura Ruby on Rails e divirta-se!

All Articles