Un nouveau regard sur le développement Fullstack avec le framework Ruby on Rails

Est-il possible de discuter sérieusement du développement fullstack? Si vous regardez vers de grands cadres pour le frontend et le backend, alors parler de fullstack semble douteux. Je suggère de regarder le terme fullstackdu point de vue de Ruby on Rails et des principes plus simples de mise en œuvre de l'interactivité sur les pages Web classiques. Je vous présente un aperçu des fonctionnalités frontales fournies dans le cadre Ruby on Rails ou liées à celui-ci.

image


Ruby on Rails est un framework MVC qui se concentre sur un développement rapide et accorde une grande attention au maintien de la cohérence au sein du projet (afin qu'il ne se révèle pas "de toute façon" "rapidement"). Il fournit de nombreux outils pour le développement backend et frontend. Dans le sens classique du fullstack, il y a eu une omission momentanée en raison de l'ignorance de son développement et d'une conception erronée du décalage des fonds utilisés. L'objectif de cet article est de mettre en évidence le développement de l'approche fullstack et le nombre de possibilités intéressantes qui y sont apparues.

Webpacker


Webpacker est un joyau livré avec Ruby on Rails.

Webpacker fournit un wrapper sur Webpack: commandes pour la connexion et le démarrage des configurations pour le travail. Webpacker établit de facto la norme pour travailler avec le frontend dans Ruby on Rails, promeut l'utilisation des dernières fonctionnalités JavaScript et des principes modernes de travail avec le code (structure, modularité, assemblage et bien plus encore).

Webpacker définit les configurations générales nécessaires pour démarrer et la structure de l'application, ce qui augmente la certitude et simplifie la compréhension du projet par différents développeurs. Pour le code JavaScript, le dossier app/javascript/avec le fichier principal est alloué app/javascript/packs/application.js.

Fichiers et dossiers ajoutés par 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


Webpacker démarre par défaut pendant le processus de création d'une nouvelle application et effectue ses paramètres. Vous pouvez créer l'application immédiatement avec des configurations supplémentaires pour Stimulus, Vue, Typescript ou une autre dans la liste fournie :

rails new myapp --webpack=stimulus

Ou installez des configurations supplémentaires après avoir créé l'application:

bundle exec rails webpacker:install:stimulus

Développer Frontend avec le framework Ruby on Rails = utiliser les approches de développement JavaScript les plus récentes. Toute la commodité de l'utilisation des normes JavaScript modernes est bien intégrée à Ruby on Rails. Les configurations nécessaires sont fournies pour travailler avec Webpack, ce qui vous permet d'être moins distrait par l'organisation correcte du projet et de vous concentrer sur la résolution de tâches courantes en utilisant l'environnement familier.

Turbolinks


Turbolinks est la bibliothèque JavaScript fournie avec Ruby on Rails.

La tâche prioritaire de Turbolinks est d'alléger la charge sur le serveur et de réduire les «coutures» lors de la navigation vers les URL des applications. Cette fonctionnalité est souvent comparée à SPA, car elle donne l'impression d'un nouveau rendu du contenu dans le navigateur au lieu de simples transitions entre les pages.

Principe de fonctionnement de Turbolinks: pour naviguer entre les pages non pas par une transition standard vers une nouvelle adresse, mais en remplissant une requête à cette adresse «en arrière-plan» via ajax, en chargeant la réponse en JavaScript, et en remplaçant le contenu de la page par une nouvelle. Ce processus s'accompagne d'événements spéciaux qui vous permettent d'ajouter des fonctionnalités à la transition entre les pages et de revenir aux pages précédentes. Par exemple,
  • pour démarrer la transition vers une autre adresse turbolinks:click, turbolinks:before-visit, turbolinks:visit:;
  • ou le traitement d'une demande de nouvelle page turbolinks:request-start, turbolinks:request-end:;
  • ou sur le processus d'affichage d'une nouvelle page turbolinks:before-render, turbolinks:render, turbolinks:load.

De plus, Turbolinks possède une barre de progression, met en cache l'historique des pages chargées et vous permet de spécifier des éléments de page non mis à jour.

Câble d'action


ActionCable fait partie du framework Ruby on Rails. ActionCable permet de travailler avec des sockets Web. Pour lister les canaux sur le serveur, un dossier app/channels/avec les fichiers primaires channel.rbet est fourni connection.rb. Pour implémenter la connexion à ces canaux - un dossier app/javascript/channels/avec des fichiers index.jset consumer.js.

Il est préférable de se familiariser immédiatement avec les possibilités d'ActionCable avec un exemple. La connexion la plus simple aux sockets Web avec son aide peut être implémentée en quelques étapes seulement.

  1. Créer un fichier de chaîne

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

  2. Créer un abonnement à cette chaîne
    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}!`
      }
    })
    


Et la connexion aux sockets Web est prête.

Maintenant, pour le vérifier, nous avons besoin d'une page simple et d'une action pour l'envoi. Pour ce faire, créez un contrôleur et ajoutez ses adresses aux routes

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"


Nous démarrons l'application, allons à l'adresse 127.0.0.1haps000 / hello et ouvrons la console du navigateur, vous y verrez la journalisation des messages provenant du serveur via des sockets Web.

Ensuite, nous envoyons une demande de mailing d'action:

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

Et regardez la page / hello et la sortie dans sa console.

Aides de formulaire et Rails-ujs


Il convient de noter certaines fonctionnalités non nouvelles, mais bien établies du cadre Ruby on Rails. Parmi eux, des aides pour les représentations et les formes. La commodité initiale des assistants est qu'ils facilitent l'intégration du balisage avec les modèles, les configurations et d'autres composants backend. L'avantage des assistants de formulaire par rapport au balisage conventionnel est la possibilité de lister rapidement les champs de formulaire sans entrer dans les détails de leur liaison aux attributs de modèle - en utilisant des assistants, la relation entre eux sera formée automatiquement. Un fragment montrant un exemple de liaison de champs de formulaire avec des paramètres de contrôleur et des attributs de modèle:

app / vues / 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


Vous pouvez en savoir plus sur cet exemple ici et ici .

Rails-ujs


Rails-ujs est la partie centrale du framework Ruby on Rails pour JavaScript discret.
Rails-ujs fournit plusieurs options supplémentaires pour les éléments de page qui modifient ou étendent leur fonctionnement.

Option distante - conçue pour les éléments qui accèdent au serveur (liens, formulaires) pour effectuer des demandes asynchrones. Exemple de lien:

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

Pour afficher les résultats de cette requête nécessite une manipulation supplémentaire, par exemple, l' ajout de gestionnaire à des événements à distance: ajax:success, ajax:error, ajax:complete.

L'option de confirmation - vous permet de demander la confirmation de l'action avant son exécution.

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


Option Disable_with - vous permet de désactiver un élément après une action
<%= form.submit data: { disable_with: "..." } %>

De plus, Rails-ujs possède plusieurs fonctionnalités pratiques. En voici quelques-unes:

Rails.fire(obj, name, data)- fonction d'appel d'événement
Rails.ajax(options)- wrapper sur XMLHttpRequest
Rails.isCrossDomain(url)- vérification de l'url appartenant à un autre domaine
Rails.$(selector)- wrapper sur document.querySelectorAll Vous pouvez les

connecter à votre code avec la commande

import Rails from "@rails/ujs"

Stimulus


Stimulus - Framework JavaScript des développeurs Ruby on Rails.

Stimulus est l'un des rares frameworks et unique à sa manière, car il implémente le développement frontend en utilisant de nouvelles approches JavaScript, alors qu'il ne cherche pas à contrôler toutes vos actions et ne vous oblige pas à séparer le frontend du backend.

La tâche de base de Stimulus est de lier les gestionnaires aux événements. Selon Stimulus, le code source doit être placé sur les classes de contrôleur, et leurs méthodes doivent être utilisées comme gestionnaires. Par défaut, le dossier app/javascript/controllers/contenant le fichier principal est alloué aux contrôleurs de stimulation dans le projet index.js. Ici, nous pouvons ajouter nos contrôleurs, pour cela, nous devons créer un fichier avec un suffixe _controller.js, par exemple,articles_controller.js. Ensuite, le chargeur Stimulus importe ces fichiers et connecte les contrôleurs aux blocs correspondants sur nos pages.

Les contrôleurs de Stimulus disposent d'équipements supplémentaires: initialisation de l'objet contrôleur ( initialize), aides pour accéder aux éléments à l'intérieur du bloc ( targets, cibles), attacher l'objet contrôleur au bloc ( connect) et se déconnecter de celui-ci ( disconnect), accéder aux attributs de données du bloc ( this.data.get). Ce qui suit est un exemple de bloc avec état actif / inactif écrit en Stimulus.

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";
  }
}


Malgré la préservation des anciens principes de mise en œuvre de la fonctionnalité interactive sur les pages classiques, l'approche de développement avec Stimulus est considérablement améliorée: la structure du code source est structurée d'une nouvelle manière, la liaison des gestionnaires aux événements est modifiée, un équipement supplémentaire est fourni. Grâce à ces commodités et à sa simplicité, le cadre Stimulus vous permet de structurer rapidement et avec compétence même une grande interface.

De plus, il convient de souligner que Stimulus se combine bien avec d'autres fonctionnalités de Ruby on Rails - une émergence utile apparaît dans presque tous les bundles.

Stimulus et Webpacker


Webpacker fournit des commandes pour créer une application avec un stimulus connecté:

rails new myapp --webpack=stimulus

Ou pour le connecter à un projet déjà créé:

bundle exec rails webpacker:install:stimulus

Stimulus et JavaScript


Stimulus encourage l'utilisation des principes de développement JavaScript modernes pour implémenter l'interactivité sur vos pages. Avec Stimulus, la solution frontend est construite de manière modulaire, la POO est utilisée pour les gestionnaires d'événements et le code est soigneusement structuré. À l'aide de l'outil de ciblage, à l'aide de contrôleurs de stimulus, il est pratique de contrôler la connexion aux éléments de bloc de composants graphiques complexes extraits de bibliothèques tierces ou écrits indépendamment (calendriers, auto-compilateurs, listes, arborescences, etc.). Grâce à cela, Stimulus est l'un des moyens les plus simples de passer des outils frontaux obsolètes et d'obtenir la productivité nécessaire grâce à l'utilisation de JavaScript pur et moderne.

Stimulus et rubis sur les rails


Avec la structure de code recommandée par Stimulus, vous continuez à écrire en JavaScript de la même manière que dans Ruby on Rails. Vous déclarez également des contrôleurs, vous liez également des actions aux méthodes. Avec Stimulus, le développement du frontend devient similaire au backend, ce qui facilite le travail là-bas et là-bas.

Stimulus et ActionCable


En utilisant les méthodes d'initialisation et de connexion dans les contrôleurs de stimulus, il est pratique de lier les sockets Web non pas à la page entière, mais à ses blocs individuels et de travailler avec précision les messages entrants. Il devient plus facile d'organiser plusieurs flux parallèles sur une seule page avec une commutation de canal indépendante.

Stimulus et Turbolinks


Stimulus est activé dès que Turbolinks charge la page; aucune manipulation supplémentaire n'est nécessaire pour connecter Stimulus aux blocs de la page.

Turbolinks facilite non seulement le chargement des pages, mais met également en cache leur contenu lors de la transition. Lorsque vous revenez à la page mise en cache à partir de l'historique, Stimulus est activé automatiquement, comme lors du chargement d'une nouvelle page. Si vous souhaitez enregistrer certaines valeurs avant de déconnecter le contrôleur de l'unité, vous pouvez utiliser la méthode disconnect- puis, lors du retour et de la connexion du contrôleur, il pourra restaurer son dernier état. Dans le code du premier exemple de travail avec Stimulus, vous pouvez voir comment, lors de la déconnexion ( disconnect), la valeur est fixée dans l'attribut data du bloc contrôleur this.active, et lors de la connexion ( connect), elle est extraite en retour.

Le retour dans les pages peut être un moyen utile de travailler avec l'application. Par exemple, lorsque vous travaillez avec un formulaire, il peut être nécessaire de remplir / modifier la valeur dans le répertoire sur une autre page, puis de retourner et de sélectionner de nouvelles données.

Un autre exemple: disons que nous devons modifier ou voir les valeurs sur la page des paramètres du chat Web. Il nous sera utile, lors de la déconnexion du contrôleur de l'unité avec la conversation, de se souvenir de l'identifiant du dernier message, donc lors du retour, demandez d'abord les nouveaux messages manquants, puis ouvrez la connexion via des sockets Web.

Ainsi, un retour sur l'historique des pages peut être utilisé comme un moyen pratique de travailler avec votre application Web.

Formulaires de stimulation et d'aide


Stimulus travaille en étroite collaboration avec le balisage, et avec l'aide d'aides, les données sont facilement incorporées dans des blocs html, grâce à cela, une partie des données peut être chargée dans l'attribut de données du bloc et livrée au contrôleur.

app / vues / 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 (extrait)
//   
//   initialize  app/javascript/controllers/articles_controller.js
initialize() {
  this.attributes = JSON.parse(this.data.get("attributes"));
  //   
  // ...
}


Stimulus et Rails-ujs


À l'aide de Stimulus et d'options à distance, vous pouvez connecter directement les contrôleurs aux événements ajax et traiter les résultats des requêtes. Déclarez le lien à l'aide de Rails-ujs et attachez-y un gestionnaire de stimulus.

lien avec option à distance et gestionnaire de stimulus
<%= link_to " ",
  article_path(article, format: :html),
  data: { remote: true, action: "ajax:success->articles#showArticle" } %>


Lorsque vous cliquez sur ce lien, une demande Ajax asynchrone au contrôleur de rails articles_controller.rbpour l'action show se produit . Dès réception d'une réponse positive, un événement se déclenche ajax:successet la méthode showArticledu contrôleur est appeléeapp/javascript/controllers/articles_controller.js

contrôleur showArticle méthode app / javascript / controllers / articles_controller.js
showArticle(e) {

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

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

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


Et après?


Ces outils, associés au framework Ruby on Rails, ouvrent de nouveaux horizons pour le développement fullstack. De plus, les outils décrits sont relativement simples et ne nécessitent pas de longues plongées - tout ce qui est nécessaire pour un projet réussi est en surface.

Créez des applications Web avec des outils de développement fullstack modernes et rapides avec le framework Ruby on Rails et profitez-en!

All Articles