L'auteur du matériel, dont nous publions la traduction aujourd'hui, souhaite partager une histoire sur les technologies qu'il utilise pour développer rapidement des prototypes d'applications Web. Ces technologies incluent les bibliothèques Fastify et Preact. Il utilise également la bibliothèque htm. Il s'intègre facilement à Preact et est utilisé pour décrire les éléments DOM à l'aide de constructions intuitives rappelant JSX. Dans le même temps, un transcripteur comme Babel n'est pas nécessaire pour travailler avec. Après avoir démontré les outils de développement de prototypage et les méthodes de travail avec celui-ci, l'auteur du matériel montrera comment emballer ces applications dans des conteneurs Docker. Cela facilite la démonstration des applications à toutes les personnes intéressées.

Commencer
J'ai commencé à utiliser l'ensemble des technologies susmentionnées il y a quelques semaines lorsque je devais créer un prototype d'application Web très simple conçu pour vérifier, avec des collègues, certaines hypothèses.
Mon expérience a été extrêmement réussie. J'ai pu créer un prototype très rapidement, mes collègues ont pu l'expérimenter facilement, ils ont pu exprimer rapidement leurs impressions à ce sujet. Dans le même temps, ils pouvaient tester le projet même si Node.js et NPM n'étaient pas installés sur leurs ordinateurs.
Tout cela m'a conduit à l'idée que je devrais écrire du matériel sur mon approche du prototypage rapide d'applications Web. Il est possible que cette approche soit utile à quelqu'un d'autre. Pour ceux qui connaissent déjà Fastify et Preact, je décrirai immédiatement la chose la plus importante, qui leur permettra de mettre immédiatement mes idées en pratique.
Idées principales
Si vous êtes déjà familier avec Fastify et Preact et que vous souhaitez apprendre à organiser le développement de projets basés sur ces technologies, vous êtes littéralement à quelques pas de ce que vous voulez. À savoir, nous parlons des commandes suivantes:
git clone https://github.com/lmammino/fastify-preact-htm-boilerplate.git my-new-project cd my-new-project rm -rf .git npm install 
Bien sûr, vous pouvez remplacer le nom du projet, 
my-new-project , par le nom de votre projet.
Après avoir installé tout ce dont vous avez besoin, vous pouvez commencer à travailler sur le projet. À savoir, nous parlons de ce qui suit:
- Le dossier src/uicontient les fichiers de la partie client de l'application (ici Preact et htm sont utilisés).
- Le dossier src/servercontient des fichiers liés au côté serveur de l'application (Fastify est utilisé ici).
En modifiant les fichiers appropriés, vous pouvez exécuter le projet:
 npm start 
Après cela, vous pouvez le tester en allant à l'adresse 
localhost:3000 dans le navigateur.
Et encore une chose. Si vous avez aimé mon développement, je serai extrêmement reconnaissant à la star de 
GitHub .
Examinons maintenant les technologies utilisées ici et les fonctionnalités de leur utilisation.
Fastify
Fastify est un framework web rapide et économique pour Node.js. Ce projet a été à l'origine créé par deux programmeurs. Maintenant, l'équipe de ceux qui y travaillent compte 10 personnes, plus de 130 personnes aident au développement du projet, il a récolté près de 10 000 étoiles sur GitHub.
Fastify a été influencé par les frameworks Node.js comme Express et Hapi, qui existent depuis un certain temps. Il était à l'origine destiné à la productivité, à la convenance des programmeurs et à étendre ses capacités à l'aide de plugins. C'est d'ailleurs l'une de mes fonctionnalités préférées de Fastify.
Si vous n'êtes pas familier avec le framework Fastify ou si vous voulez mieux le connaître, je peux recommander sa 
documentation officielle.
Il convient de noter que je suis lié à Fastify. Je suis membre de la principale équipe de développement et je suis principalement engagé dans le support du site du projet et dans l'élaboration de sa documentation.
Preact
Preact est une bibliothèque pour développer des interfaces utilisateur pour des projets Web, qui a été créée par une seule personne en remplacement rapide et compact de React. Ce projet s'est avéré être un succès, maintenant toute une équipe de développeurs s'y est engagée, sur GitHub il a marqué plus de 20 000 étoiles.
L'une des raisons pour lesquelles j'aime Preact est que cette bibliothèque possède une couche extensible pour décrire les composants visuels de l'application. Dans des circonstances normales, cette bibliothèque peut être utilisée à l'aide de JSX en combinaison avec Babel pour traduire le code, mais si vous ne souhaitez pas installer Babel et configurer le processus de génération d'application, vous pouvez utiliser Preact, par exemple, avec la bibliothèque 
htm , qui utilise des littéraux de modèle et ne nécessite pas transpilation lors du lancement de projets dans lesquels il est utilisé dans les navigateurs modernes.
Dans cet article, nous utiliserons la bibliothèque htm et considérerons bientôt quelques exemples.
Aperçu du projet
Ici, nous regardons l'ensemble du processus de création d'un projet. Notre objectif sera de développer une application web simple qui affiche des informations sur l'heure sur le serveur au moment de son lancement. Ici, afin de clarifier ce que nous visons.
Application dans le navigateurIl s'agit d'une application monopage (SPA), dans laquelle Preact et htm sont utilisés pour former sa partie client, et Fastify est utilisé pour créer une API conçue pour recevoir l'heure du serveur.
Un lecteur attentif peut remarquer que la page montrée dans la figure précédente a une jolie icône de favicon. Certes, il est très petit là-bas, donc je vais faciliter la tâche à ceux qui, en se brisant les yeux, essaient de comprendre. En voici une version agrandie.
FaviconConfiguration du côté serveur de l'application
Commençons par créer un nouveau dossier:
 mkdir server-time cd server-time 
Maintenant, initialisez le projet NPM et installez Fastify:
 npm init -y npm i --save fastify@next fastify-static@next fastify-cli 
Veuillez noter que j'ai utilisé la construction 
@next pour décrire certains 
@next dépendances. Ceci est fait pour que le projet utilise la bibliothèque Fastify 2, qui est actuellement dans un état candidat de sortie, mais deviendra très bientôt la version stable principale.
Veuillez noter que vous pouvez également créer un nouveau projet basé sur Fastify à l'aide de l' 
fastify-cli ligne de commande 
fastify-cli :
 npx fastify-cli generate server-time 
Au moment de la rédaction de ce document, cette équipe crée un projet conçu pour utiliser Fastify 1.x, mais très bientôt, après la sortie de Fastify 2, cet outil sera mis à jour.
Analysons les packages installés:
- fastifyest un composant central du framework.
- fastify-staticest un plugin supplémentaire qui vous permet de servir facilement des fichiers statiques avec le serveur Fastify.
- fastify-cliest un outil en ligne de commande qui vous permet de créer des projets basés sur Fastify.
Pour le moment, nous sommes prêts à créer une API basée sur Fastify. 
src/server/server.js donc le code du serveur dans le 
src/server/server.js :
 const path = require('path') module.exports = async function(fastify, opts) { //      `src/ui` fastify.register(require('fastify-static'), {   root: path.join(__dirname, '..', 'ui'), }) //     API fastify.get('/api/time', async (request, reply) => {   return { time: new Date().toISOString() } }) } 
Je crois que le code ci-dessus s'explique bien, mais il y a quelques détails intéressants qui méritent d'être mentionnés. Cela sera particulièrement utile pour ceux qui n'ont pas d'expérience avec Fastify.
La première chose à laquelle vous pouvez prêter attention dans ce code est que le mot-clé 
async est utilisé ici. Fastify prend en charge à la fois le développement de style asynchrone / attente et une approche de rappel plus traditionnelle. Le choix exact dépend des préférences d'un développeur particulier.
Un autre détail intéressant est que nous définissons ici le serveur comme un module exporté. Ce module (appelé «plug-in» dans le jargon Fastify) est une fonction qui prend comme argument une instance de Fastify ( 
fastify ) et un ensemble d'options ( 
fastify ). Dans la déclaration du module, nous pouvons utiliser une instance de 
fastify pour enregistrer les plugins. C'est exactement ce qui se passe avec le plugin 
fastify-static . Nous pouvons également décrire les points de terminaison HTTP à l'aide de méthodes spéciales telles que 
fastify.get et 
fastify.post .
L'approche modulaire utilisée ici, même si elle semble un peu inhabituelle, a ses avantages. Pour commencer, il convient de noter qu'il vous permet de combiner plusieurs serveurs. Imaginez que vous avez créé un serveur conçu pour servir un blog et un autre pour un forum. Ils peuvent être facilement intégrés dans une application existante en les attachant à des chemins tels que 
/blog et 
/forum .
De plus, cette approche nous permet d'abstraire des applications et des sous-applications des liaisons de serveur (par exemple, la liaison de socket), en passant la solution à cette tâche soit à l'application racine soit à 
fastify-cli .
Démarrez le serveur à l'aide de l' 
fastify ligne de commande 
fastify :
 node_modules/.bin/fastify start --log-level info src/server/server.js 
Afin de simplifier notre vie, nous pouvons ajouter cette commande Ă  la section 
scripts de notre fichier 
package.json :
 { "scripts": {   "start": "fastify start --log-level info src/server/server.js" } } 
Avant de démarrer le serveur, nous devons nous assurer qu'il existe un dossier dans lequel les ressources statiques seront situées. Sinon, 
fastify-static erreur. Créez ce dossier:
 mkdir src/ui 
Nous pouvons maintenant démarrer l'application avec la commande 
npm start et naviguer Ă  l'aide du navigateur vers 
localhost:3000/api/time .
Si tout fonctionne correctement, dans le navigateur, vous pouvez voir quelque chose comme ceci:
 { "time": "2019-02-17T19:32:03.354Z" } 
À ce stade, vous pouvez apprécier une autre fonctionnalité intéressante de Fastify. Elle réside dans le fait que la sérialisation JSON, dans le cas où une certaine route retourne un objet, est appliquée automatiquement.
Maintenant, le travail sur l'API du serveur est terminé. Ayons une interface.
Configuration frontend
Tout le code de notre projet lié au frontend sera situé dans le dossier 
src/ui . Il sera composé de 5 fichiers:
- app.js- Code d'application- app.js-activé.
- bootstrap.min.css- Code CSS pour le style de l'application (il provient directement du framework Bootstrap).
- favicon.ico- fichier favicon. Si vous développez une application sérieuse, vous ne pouvez pas vous passer d'un bon fichier favicon.
- index.htmlest le fichier HTML principal de notre application d'une page.
- preacthtm.js- code des bibliothèques Preact et htm.
Tout d'abord, placez les fichiers dans le dossier, qui sont les styles, les bibliothèques et l'icône favicon:
 curl "https://unpkg.com/htm@2.0.0/preact/standalone.js" > src/ui/preacthtm.js curl "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" > src/ui/bootstrap.min.css curl "https://github.com/lmammino/fastify-preact-htm-boilerplate/blob/master/src/ui/favicon.ico?raw=true" > src/ui/favicon.ico 
Créez maintenant le fichier 
src/ui/index.html :
 <!DOCTYPE html> <html lang="en"> <head>   <meta charset="utf-8" />   <meta     name="viewport"     content="width=device-width, initial-scale=1, shrink-to-fit=no"   />   <!-- Bootstrap CSS -->   <link rel="stylesheet" href="/bootstrap.min.css" />   <title>My awesome server time</title> </head> <body>   <div id="app"></div>   <!-- JavaScript -->   <script src="/preacthtm.js"></script>   <script src="/app.js"></script> </body> </html> 
Nous avons devant nous une page HTML très ordinaire avec laquelle nous chargeons toutes les ressources (CSS et JS) et créons un élément 
<div> vide avec l' 
app identifiant, dans lequel nous sortirons notre application pendant l'exécution du projet.
Jetez maintenant un œil au code de l'application, qui devrait se trouver dans le 
src/ui/app.js :
 /*  htmPreact */ const { html, Component, render } = htmPreact class App extends Component { componentDidMount() {   this.setState({ loading: true, time: null })   fetch('/api/time')     .then(response => response.json())     .then(data => this.setState({ loading: false, time: data.time })) } render(props, state) {   return html`     <div class="container mt-5">       <div class="row justify-content-center">         <div class="col">           <h1>Hello from your new App</h1>           <div>             ${state.loading &&               html`                 <p>Loading time from server...</p>               `} ${state.time &&               html`                 <p>Time from server: <i><font color="#999999">${state.time}</font></i> </p>               `}           </div>           <hr />           <div>             Have fun changing the code from this boilerplate:             <ul>               <li>UI code available at <code>/src/ui</code></li>               <li>Server-side code available at <code>/src/server</code></li>             </ul>           </div>         </div>       </div>     </div>   ` } } render( html`   <${App} /> `, document.getElementById('app') ) 
Il n'y a qu'un seul composant avec état dans cette application appelé 
App . L'état de ce composant comprend 2 variables:
- loadingest une variable logique utilisée pour indiquer si une demande à l'API du serveur est en cours d'exécution à un certain moment pour obtenir des informations sur l'heure du serveur.
- time- une chaîne qui contient les dernières informations d'heure reçues du serveur.
Si vous connaissez React, vous pouvez facilement comprendre le code ci-dessus.
En utilisant Preact et htm, nous pouvons créer des composants en déclarant des classes qui étendent la classe 
Component intégrée.
Dans cette classe, nous pouvons décrire le comportement d'un composant en utilisant des méthodes de cycle de vie, comme 
componentDidMount() , et également utiliser une méthode qui se comporte comme une méthode 
render() standard de React.
Dans notre cas, dès que le composant est attaché à la page (méthode 
componentDidMount() ), nous définissons la propriété de 
loading état et exécutons une demande d'API à l'aide de 
fetch .
Une fois la demande terminée, nous définissons la valeur de la propriété d'état 
time et redéfinissons la propriété de 
loading sur 
false .
La méthode 
render() est appelée automatiquement chaque fois qu'un état de composant change ou lorsque de nouvelles propriétés lui sont transmises. Dans cette méthode, nous décrivons le composant DOM en utilisant htm.
La bibliothèque htm vous permet de décrire les nœuds DOM à l'aide de littéraux de modèle balisés avec une balise spéciale - 
html . Dans notre littéral de modèle, des expressions dynamiques peuvent être présentes, comme celles que nous utilisons pour vérifier l'état et décider quoi afficher si l'application charge des données à partir du serveur et si les données sont déjà chargé.
Il convient également de noter que nous devons créer une instance de l'application et l'afficher sur une page HTML. Cela se fait à l'aide de la fonction 
render() de l'objet global 
htmPreact .
Le travail sur l'application frontale est maintenant terminé. Vous pouvez redémarrer le serveur, aller sur 
localhost:3000 et expérimenter avec ce que nous venons de créer. Par exemple, vous pouvez développer le vôtre sur la base de cette application. Et lorsque ce que vous construisez semble suffisamment intéressant pour le montrer à quelqu'un d'autre, il vous sera probablement utile de placer votre application dans un conteneur Docker.
Conteneurisation des applications
Je crois que la meilleure façon de montrer aux autres vos nouveaux petits projets est d'utiliser les capacités de Docker à cet effet.
Grâce à Docker, quiconque essaie d'exécuter votre application à la maison sera libre de penser s'il a la version appropriée de Node.js et NPM installée, il n'aura pas besoin de télécharger le code source de l'application pour s'en assurer en entrant la séquence correcte de commandes , installez ses dépendances et démarrez le serveur.
Afin d'emballer l'application dans le conteneur Docker, nous devons créer un 
Dockerfile très simple dans le dossier racine de notre projet:
 FROM node:11-alpine WORKDIR /app COPY . /app RUN npm install --production EXPOSE 3000 CMD ["npm", "start"] 
Nous décrivons ici les actions suivantes:
- L'image est créée sur la base de l'image Node.js 11, construite sur la base d'Alpine Linux.
- Tout dans le dossier actuel est copié dans le dossier /appdu conteneur.
- Après cela, nous npm installcommandenpm installpour télécharger et installer les dépendances. L'utilisation de l'indicateur--productionconduit au fait que seules les dépendances nécessaires au déploiement du projet en production seront installées. Cela accélère la création d'images si le projet utilise de nombreuses dépendances de développement.
- Nous indiquons que le conteneur doit avoir un pore ouvert 3000, sur lequel, par défaut, le serveur fonctionnera.
- Au final, nous décrivons une commande, npm start, qui sera exécutée au démarrage du conteneur. Elle lance l'application.
Afin de collecter l'image pour le conteneur, exécutez la commande suivante:
 docker build -t server-time . 
Après quelques secondes, l'image devrait être prête et vous devriez pouvoir démarrer le conteneur:
 docker run -it -p 3000:3000 server-time 
L' 
-p vous permet de configurer la connexion entre le port de conteneur 3000 et le port local 3000. Cela vous permettra d'accéder à l'application conteneurisée sur 
localhost:3000 .
Vous êtes maintenant prêt à partager votre application avec d'autres personnes. Pour l'exécuter dans l'environnement Docker, il suffit, à condition que Docker soit installé sur l'ordinateur, d'exécuter les deux commandes ci-dessus dans son dossier.
Résumé
Dans cet article, nous avons expliqué comment créer un environnement pour le développement rapide d'applications Web à l'aide de Fastify et Preact. En outre, nous avons expliqué comment partager l'application avec d'autres personnes utilisant Docker.
Comme mentionné ci-dessus, les outils proposés sont conçus pour un prototypage rapide, alors maintenant vous vous demandez peut-être ce qui manque ici pour développer de vraies applications. Très probablement, lorsque vous parlez de «vraies applications», vous entendez les caractéristiques suivantes:
- Compilation des ressources de la partie front-end de l'application: création de fichiers optimisés (bundles), éventuellement à l'aide de Webpack, Babel ou d'autres outils.
- Routage dans le front-end de l'application.
- Rendu du serveur
- Moyens de stockage permanent des données.
Toutes ces possibilités de développement d'applications réelles n'ont pas encore été ajoutées à l'ensemble des technologies discutées ici, donc pour l'instant je le perçois comme un outil de développement de prototypes. Je suis sûr que si vous avez aimé ce que vous avez vu et que vous considérez tout cela comme la base de futures applications qui résolvent de vrais problèmes, vous pouvez facilement trouver ce dont vous avez besoin et créer des applications prêtes à l'emploi sur Fastify et Preact. version de production.
Chers lecteurs! Comment prototyper des applications Web?
