Uso de Fastify y Preact para prototipar r√°pidamente aplicaciones web

El autor del material, cuya traducción publicamos hoy, quiere compartir una historia sobre las tecnologías que utiliza para desarrollar rápidamente prototipos de aplicaciones web. Estas tecnologías incluyen las bibliotecas Fastify y Preact. También usa la biblioteca htm. Se integra fácilmente con Preact y se utiliza para describir elementos DOM utilizando construcciones intuitivas que recuerdan a JSX. Al mismo tiempo, no se necesita un transpilador como Babel para trabajar con él. Después de demostrar las herramientas de desarrollo de prototipos y los métodos para trabajar con él, el autor del material mostrará cómo empaquetar dichas aplicaciones en contenedores Docker. Esto facilita la demostración de aplicaciones a todos los interesados.



Inicio


Hace unas semanas, utilic√© el conjunto de tecnolog√≠as antes mencionado cuando necesitaba crear una aplicaci√≥n web prototipo muy simple dise√Īada para probar, junto con mis colegas, algunas suposiciones.

Mi experimento fue extremadamente exitoso. Pude crear un prototipo muy rápido, los colegas tuvieron la oportunidad de experimentar con él convenientemente, pudieron expresar rápidamente sus impresiones al respecto. Al mismo tiempo, podrían probar el proyecto incluso si Node.js y NPM no estuvieran instalados en sus computadoras.

Todo esto me llev√≥ a la idea de que deber√≠a escribir material sobre mi enfoque para la creaci√≥n r√°pida de prototipos de aplicaciones web. Es posible que este enfoque sea √ļtil para otra persona. Para aquellos que ya est√°n familiarizados con Fastify y Preact, describir√© de inmediato lo m√°s importante, lo que les permitir√° poner en pr√°ctica mis ideas de inmediato.

Ideas principales


Si ya est√° familiarizado con Fastify y Preact y desea aprender sobre c√≥mo organizar el desarrollo de proyectos basados ‚Äč‚Äčen estas tecnolog√≠as, entonces est√° literalmente a un par de pasos de lo que desea. A saber, estamos hablando de los siguientes comandos:

git clone https://github.com/lmammino/fastify-preact-htm-boilerplate.git my-new-project cd my-new-project rm -rf .git npm install 

Por supuesto, puede cambiar el nombre del proyecto, my-new-project , al nombre de su proyecto.

Después de instalar todo lo que necesita, puede comenzar a trabajar en el proyecto. A saber, estamos hablando de lo siguiente:

  • La carpeta src/ui contiene archivos de la parte cliente de la aplicaci√≥n (aqu√≠ se utilizan Preact y htm).
  • La carpeta src/server contiene archivos relacionados con el lado del servidor de la aplicaci√≥n (aqu√≠ se usa Fastify).

Al editar los archivos apropiados, puede ejecutar el proyecto:

 npm start 

Después de eso, puede probarlo yendo a la dirección localhost:3000 en el navegador.

Y una cosa más. Si te gustó mi desarrollo, estaré inmensamente agradecido por la estrella en GitHub .

Ahora echemos un vistazo a las tecnologías utilizadas aquí y las características de trabajar con ellas.

Fastify


Fastify es un marco web rápido y económico para Node.js. Este proyecto fue creado originalmente por dos programadores. Ahora, el equipo de quienes trabajan en él tiene 10 personas, más de 130 personas ayudan en el desarrollo del proyecto, recolectó casi 10,000 estrellas en GitHub.

Fastify fue influenciado por los frameworks Node.js como Express y Hapi, que han existido durante bastante tiempo. Originalmente estaba dirigido a la productividad, a la conveniencia de los programadores y a expandir sus capacidades con la ayuda de complementos. Esta, por cierto, es una de mis características favoritas de Fastify.

Si no está familiarizado con el marco de Fastify o desea conocerlo mejor, puedo recomendar su documentación oficial.

Cabe se√Īalar que estoy relacionado con Fastify. Soy miembro del equipo principal de desarrollo y me dedico principalmente a apoyar el sitio del proyecto y a trabajar en su documentaci√≥n.

Preact


Preact es una biblioteca para desarrollar interfaces de usuario para proyectos web, que fue creada por una persona como un reemplazo compacto y rápido para React. Este proyecto resultó ser bastante exitoso, ahora todo un equipo de desarrolladores está involucrado en él, en GitHub obtuvo más de 20,000 estrellas.

Una de las razones por las que me gusta Preact es que esta biblioteca tiene una capa extensible para describir los componentes visuales de la aplicación. En circunstancias normales, esta biblioteca se puede usar usando JSX en combinación con Babel para traducir el código, pero si no desea instalar Babel y configurar el proceso de compilación de la aplicación, puede usar Preact, por ejemplo, junto con la biblioteca htm , que usa plantillas literales y no requiere transpilación al iniciar proyectos en los que se utiliza en navegadores modernos.

En este artículo usaremos la biblioteca htm y pronto consideraremos algunos ejemplos.

Resumen del proyecto


Aquí nos fijamos en todo el proceso de creación de un proyecto. Nuestro objetivo será desarrollar una aplicación web simple que muestre información sobre la hora en el servidor en el momento de su lanzamiento. Aquí, para que quede más claro por qué nos esforzaremos.


Aplicación en navegador

Esta es una aplicaci√≥n de p√°gina √ļnica (SPA), en la que Preact y htm se usan para formar su parte cliente, y Fastify se usa para crear una API dise√Īada para recibir el tiempo del servidor.

Un lector atento puede notar que la p√°gina que se muestra en la figura anterior tiene un √≠cono de favicon. Es cierto, √©l es muy peque√Īo all√≠, as√≠ que voy a facilitar la tarea a aquellos que, rompiendo los ojos, est√°n tratando de distinguir. Aqu√≠ hay una versi√≥n ampliada de la misma.


Favicon

Configurar el lado del servidor de la aplicación


Comencemos creando una nueva carpeta:

 mkdir server-time cd server-time 

Ahora inicialice el proyecto NPM e instale Fastify:

 npm init -y npm i --save fastify@next fastify-static@next fastify-cli 

Tenga en cuenta que usé la construcción @next al describir algunos @next dependencia. Esto se hace para que el proyecto use la biblioteca Fastify 2, que actualmente se encuentra en un estado candidato de lanzamiento, pero muy pronto se convertirá en la versión estable principal.

Tenga en cuenta que también puede crear un nuevo proyecto basado en Fastify utilizando la fastify-cli línea de comandos fastify-cli :

 npx fastify-cli generate server-time 

Al momento de escribir este material, este equipo crea un proyecto dise√Īado para usar Fastify 1.x, pero muy pronto, despu√©s del lanzamiento de Fastify 2, esta herramienta se actualizar√°.

Analicemos los paquetes instalados:

  • fastify es un componente central del marco.
  • fastify-static es un complemento adicional que le permite servir convenientemente archivos est√°ticos con el servidor Fastify.
  • fastify-cli es una herramienta de l√≠nea de comandos que le permite crear proyectos basados ‚Äč‚Äčen Fastify.

Por el momento, estamos listos para crear una API basada en Fastify. Pongamos el código del servidor en el 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() } }) } 

Creo que el c√≥digo anterior se explica bien, pero hay algunos detalles interesantes de los que vale la pena hablar. Esto ser√° especialmente √ļtil para aquellos que no tienen experiencia con Fastify.

Lo primero a lo que puede prestar atención en este código es que aquí se usa la palabra clave async . Fastify admite el desarrollo de estilo asíncrono / en espera y un enfoque de devolución de llamada más tradicional. Qué elegir exactamente depende de las preferencias de un desarrollador en particular.

Otro detalle interesante es que definimos el servidor aquí como un módulo exportado. Este módulo (esto se llama un "complemento" en la jerga de Fastify) es una función que toma una instancia de Fastify ( fastify ) y un conjunto de opciones ( opts ) como argumentos. Dentro de la declaración del módulo, podemos usar una instancia de fastify para registrar complementos. Esto es exactamente lo que sucede con el fastify-static . También podemos describir puntos finales HTTP utilizando métodos especiales como fastify.get y fastify.post .

El enfoque modular utilizado aqu√≠, aunque parece un poco inusual, tiene sus ventajas. Para empezar, debe tenerse en cuenta que le permite combinar varios servidores. Imagine que ha creado un servidor dise√Īado para servir un blog y otro para un foro. Se pueden integrar f√°cilmente en una aplicaci√≥n existente uni√©ndolos a rutas como /blog y /forum .

Además, este enfoque le permite abstraer aplicaciones y sub-aplicaciones de los enlaces del servidor (por ejemplo, enlace de socket), pasando la solución a esta tarea ya sea a la aplicación raíz o fastify-cli .

Inicie el servidor utilizando la fastify línea de comandos fastify :

 node_modules/.bin/fastify start --log-level info src/server/server.js 

Para simplificar nuestra vida, podemos agregar este comando a la sección de scripts de nuestro archivo package.json :

 { "scripts": {   "start": "fastify start --log-level info src/server/server.js" } } 

Antes de iniciar realmente el servidor, debemos asegurarnos de que haya una carpeta en la que se ubicar√°n los recursos est√°ticos. De lo contrario, fastify-static error. Crea esta carpeta:

 mkdir src/ui 

Ahora podemos iniciar la aplicación con el comando npm start y navegar usando el navegador a localhost:3000/api/time .

Si todo funciona correctamente, en el navegador puede ver algo como lo siguiente:

 { "time": "2019-02-17T19:32:03.354Z" } 

En este punto, puede apreciar otra buena característica de Fastify. Se basa en el hecho de que la serialización JSON, en el caso de que una ruta determinada devuelva un objeto, se aplica automáticamente.

Ahora se completa el trabajo en la API del servidor. Tengamos una interfaz.

Configuración frontend


Todo el código de nuestro proyecto relacionado con la interfaz se ubicará en la carpeta src/ui . Constará de 5 archivos:

  • app.js : crea el c√≥digo de la aplicaci√≥n.
  • bootstrap.min.css : c√≥digo CSS para dise√Īar la aplicaci√≥n (se toma directamente del marco Bootstrap).
  • favicon.ico : archivo favicon. Si est√° desarrollando una aplicaci√≥n seria, no puede prescindir de un buen archivo favicon.
  • index.html es el archivo HTML principal de nuestra aplicaci√≥n de una p√°gina.
  • preacthtm.js : c√≥digo de las bibliotecas Preact y htm.

Primero, coloque los archivos en la carpeta, que son estilos, bibliotecas y el ícono de 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 

Ahora cree el archivo 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> 

Tenemos ante nosotros una página HTML muy ordinaria con la que cargamos todos los recursos (CSS y JS) y creamos un elemento <div> vacío con la app identificación, en el que enviaremos nuestra aplicación durante la ejecución del proyecto.

Ahora eche un vistazo al código de la aplicación, que debe estar en el 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') ) 

Solo hay un componente con estado en esta aplicación llamado App . El estado de este componente incluye 2 variables:

  • loading es una variable l√≥gica que se usa para indicar si se est√° realizando una solicitud a la API del servidor en un determinado momento para obtener informaci√≥n sobre la hora del servidor.
  • time : una cadena que contiene la √ļltima informaci√≥n de tiempo recibida del servidor.

Si está familiarizado con React, puede comprender fácilmente el código anterior.
Usando Preact y htm, podemos crear componentes declarando clases que extienden la clase de Component incorporada.

En esta clase, podemos describir el comportamiento de un componente usando métodos de ciclo de vida como componentDidMount() , y también usar un método que se comporta como un método render() regular de React.

En nuestro caso, tan pronto como el componente se adjunte a la página (método componentDidMount() ), establecemos la propiedad de loading estado y ejecutamos una solicitud de API usando fetch .
Una vez completada la solicitud, establecemos el valor de la propiedad de estado de time y restablecemos la propiedad de loading a false .

El método render() se llama automáticamente cada vez que cambia el estado de un componente o cuando se le pasan nuevas propiedades. En este método, describimos el componente DOM usando htm.

La biblioteca htm le permite describir los nodos DOM utilizando literales de plantillas etiquetadas con una etiqueta especial: html . Dentro de nuestra plantilla literal, las expresiones dinámicas pueden estar presentes, como las que usamos para verificar el estado y decidir qué mostrar si la aplicación está cargando datos del servidor y si los datos ya están cargado

Tambi√©n vale la pena se√Īalar que necesitamos crear una instancia de la aplicaci√≥n y mostrarla en una p√°gina HTML. Esto se hace utilizando la funci√≥n render() del objeto global htmPreact .

Ahora se ha completado el trabajo en la aplicaci√≥n front-end. Puede reiniciar el servidor, vaya a localhost:3000 y experimente con lo que acabamos de crear. Por ejemplo, puede desarrollar el suyo en base a esta aplicaci√≥n. Y cuando lo que cree parezca lo suficientemente interesante como para mostr√°rselo a otra persona, probablemente le sea √ļtil empacar su aplicaci√≥n en un contenedor Docker.

Aplicación en contenedores


Creo que la mejor manera de mostrar a otros sus nuevos proyectos peque√Īos es utilizar las capacidades de Docker para este prop√≥sito.

Gracias a Docker, cualquier persona que intente ejecutar su aplicación en casa no tendrá que pensar si tiene instalada la versión adecuada de Node.js y NPM, no necesitará descargar el código fuente de la aplicación para asegurarse de que ingrese la secuencia correcta de comandos , instale sus dependencias e inicie el servidor.

Para empacar la aplicación en el contenedor Docker, necesitamos crear un Dockerfile muy simple en la carpeta raíz de nuestro proyecto:

 FROM node:11-alpine WORKDIR /app COPY . /app RUN npm install --production EXPOSE 3000 CMD ["npm", "start"] 

Aquí describimos las siguientes acciones:

  • La imagen se crea en base a la imagen Node.js 11, construida sobre la base de Alpine Linux.
  • Todo lo de la carpeta actual se copia en la carpeta /app del contenedor.
  • Despu√©s de eso, ejecutamos el comando npm install para descargar e instalar las dependencias. El uso del indicador --production lleva al hecho de que solo se instalar√°n las dependencias necesarias para la implementaci√≥n del proyecto en producci√≥n. Esto acelera la creaci√≥n de im√°genes si el proyecto usa muchas dependencias de desarrollo.
  • Indicamos que el contenedor debe tener poro abierto 3000, en el cual, por defecto, el servidor funcionar√°.
  • Al final, describimos un comando, npm start , que se ejecutar√° cuando se inicie el contenedor. Ella lanza la aplicaci√≥n.

Para recopilar la imagen para el contenedor, ejecute el siguiente comando:

 docker build -t server-time . 

Después de unos segundos, la imagen debería estar lista y debería poder iniciar el contenedor:

 docker run -it -p 3000:3000 server-time 

La -p permite configurar la conexión entre el puerto de contenedor 3000 y el puerto local 3000. Esto le permitirá acceder a la aplicación en contenedor en localhost:3000 .
Ahora está listo para compartir su aplicación con otras personas. Para ejecutarlo en el entorno Docker, es suficiente, siempre que Docker esté instalado en la computadora, para ejecutar los dos comandos anteriores en su carpeta.

Resumen


En este artículo, hablamos sobre cómo crear un entorno para el rápido desarrollo de aplicaciones web usando Fastify y Preact. Además, hablamos sobre cómo compartir la aplicación con otras personas que usan Docker.

Como se mencion√≥ anteriormente, las herramientas propuestas est√°n dise√Īadas para la creaci√≥n r√°pida de prototipos, por lo que ahora puede que se pregunte qu√© falta aqu√≠ para desarrollar aplicaciones reales. Lo m√°s probable es que cuando habla de "aplicaciones reales", se refiera a las siguientes caracter√≠sticas:

  • Compilaci√≥n de recursos de la parte front-end de la aplicaci√≥n: creaci√≥n de archivos optimizados (paquetes), posiblemente utilizando Webpack, Babel u otras herramientas.
  • Enrutamiento en el front-end de la aplicaci√≥n.
  • Representaci√≥n del servidor
  • Medios de almacenamiento permanente de datos.

Todavía no se han agregado todas estas posibilidades para desarrollar aplicaciones reales al conjunto de tecnologías discutidas aquí, por lo que por ahora lo percibo como una herramienta para desarrollar prototipos. Estoy seguro de que si te gustó lo que viste y consideras todo esto como la base para futuras aplicaciones que resuelven problemas reales, puedes encontrar fácilmente lo que necesitas y crear aplicaciones listas para Fastify y Preact lanzamiento de producción.

Estimados lectores! ¬ŅC√≥mo se prototipan las aplicaciones web?

Source: https://habr.com/ru/post/442652/


All Articles