Hola Habr!
Érase una vez, lanzamos un
proyecto piloto
en la pila MEAN (Mongo, Express, Angular, Node), que generalmente no nos decepcionó, sin embargo, decidimos no hacer impresiones y actualizaciones adicionales en ese momento, a diferencia de Manning, que
actualizó este libro . Sin embargo, continuamos buscando en esta dirección y hoy nos gustaría hablar con usted sobre la pila MERN relacionada, donde React se encuentra en el cliente, no Angular. El
piso está dado a
Tim Smith .

Advertencia: todo el código para este artículo está
aquí .
En esta guía de pila MERN, escribiremos un blog simple usando React.js, Node.js, Express.js y MongoDB para expandir nuestro arsenal de pila completa.
¿Qué es una pila?
Quizás lo primero que se debata es la idea de una "pila" como tal. Hay muchas pilas diferentes, y todas ellas son solo caminos diferentes para lograr el mismo objetivo. Al crear una aplicación de pila completa, proporcionamos la parte del cliente con la que interactuará el usuario, y la misma parte del cliente medirá el trabajo con el servidor y la base de datos, haciendo que todo este proceso sea lo más simple y manejable posible.
Podemos decir que la pila es un cierto conjunto de tecnologías utilizadas para resolver este problema.
Aunque hay muchas pilas de las que vale la pena hablar, algunas de ellas son más populares que otras en la actualidad. Una de estas pilas populares se llama MEAN, y consiste en:
- M ongoDb
- E xpress.js
- Un ngular.js
- N ode.js
Hoy hablaremos sobre la pila MERN, que es muy similar a MEAN, excepto que Angular.js se reemplaza aquí con React.js. Por lo tanto, podemos usar MongoDB como base de datos, Node.js y Express, respectivamente, para el servidor y el enrutamiento, y React.js, para crear la parte del cliente con la que el usuario interactuará.
¿Cómo se realiza el desarrollo con esta pila?
Antes de pasar a todas las sutilezas, echemos un vistazo general a cómo todos estos elementos funcionan juntos. Personalmente, me llevó un tiempo entrar en esto, ya que mi experiencia está relacionada con PHP, donde las partes del cliente y el servidor están un tanto confusas.
1. La parte del servidor (Node y Express.js) y la parte del cliente (React.js)En primer lugar, debe comprender que la parte del servidor y la parte del cliente son entidades separadas. La parte del cliente puede estar en el mismo repositorio con el servidor, o tal vez en uno completamente diferente.
2. Los terminales API se utilizan para la comunicación.Si ya está pensando en cómo hacer amigos de las partes del cliente y del servidor, le responderé: esto se hace a través de la API. Se crea una API (interfaz de programa de aplicación) en el servidor, donde obtendremos "terminales" a través de los cuales la aplicación ubicada en la parte del cliente puede interactuar con el servidor.
Expliquemos con los dedos: imagine que su mano izquierda es el lado del servidor, y su mano derecha es el lado del cliente.
Ahora dobla tus manos y gira tus dedos juntos como si estuvieras sacudiendo tu propia mano. Así es como funcionan los lenguajes de plantilla. Le permiten simplemente mostrar un marcado junto con los datos descargados con los servidores, y en ellos los componentes del cliente y del servidor se superponen en gran medida.
Ahora abre tus manos. Extienda los dedos lo más posible y haga que las manos izquierda y derecha se toquen solo con la punta de los dedos. Así es como funciona la pila MERN. La parte del servidor proporciona terminales (yemas de los dedos de la mano izquierda) para acceder al servidor, al que el cliente envía llamadas (a través de las puntas de los dedos de la mano derecha) y a través de estos puntos de contacto intercambia información con el servidor (mano izquierda).
Espero que se haya aclarado un poco, y si no, olvide toda esta metáfora, como si no la hubiera mencionado.
Nuestro lado del servidor de Node.js y Express.js
Aunque no voy a dar instrucciones paso a paso sobre cómo construir esta pila aquí (este es un tema para un artículo separado), me gustaría considerar los diversos elementos de la pila que generalmente se usan o se pueden usar en ella. Yo mismo leí varios manuales que explicaban cómo configurar el servidor, pero no explicaba por qué se usan estas bibliotecas particulares para esto.
Después de crear el archivo app.js, deberá instalar varios paquetes. Los siguientes son los paquetes más comunes que he usado previamente en mis proyectos con Express.js, tal vez también sean útiles para usted.
- Express.js es un marco para crear aplicaciones web. Tiene una funcionalidad incorporada para resolver muchos problemas, en particular, para establecer el enrutamiento.
- Mongoose es un administrador de datos de objetos (ODM) que proporciona interoperabilidad entre una aplicación express.js y una base de datos MongoDB.
- BodyParser es una biblioteca que permite que la aplicación express.js lea el cuerpo (es decir, el contenido) de las solicitudes entrantes.
- DotENV : le permite usar archivos con la extensión .env para trabajar con datos confidenciales.
- Passport.js : proporciona autenticación en nuestra aplicación y proporciona varios métodos de autenticación diferentes.
- Validator : validación simple de muchos tipos de datos
- bCrypt : cifrado de datos confidenciales, como contraseñas
- Nodemon - "reinicio en caliente" para nuestro servidor de nodos en caso de que la situación cambie; Gracias a Nodemon, no puede detener o reiniciar el servidor después de realizar cualquier cambio.
Por supuesto, hay muchos otros paquetes, pero en mi experiencia, son estas bibliotecas las que se usan con más frecuencia.
Entonces, después de clasificar algunos de los paquetes más utilizados, veamos el código. Para comenzar, nuestro servidor:

Este es un servidor API simple. Como puede ver, está equipado con la funcionalidad CRUD básica (Crear-Leer-Actualizar-Eliminar), nada sobrenatural. Mirándolo más de cerca, vemos que
res.json()
se usa aquí para proporcionar datos de salida para una URL específica, es decir, HTML u otra plantilla no se usa para la salida. Así es como construimos nuestras API abriendo el acceso a datos a React.js.
También puede notar que acabo de señalar mangosta a mi propio servidor mongodb instalado en mi computadora. Para que dicho mecanismo funcione correctamente, MongoDB debe estar instalado en su computadora y funcionar. Si no funciona, simplemente abra la ventana de la consola e ingrese el siguiente comando:

Iniciará el servidor MongoDB en su máquina local. Como todo esto se hace localmente, no podrá ver mis publicaciones si ejecuta el código desde el repositorio. Tenemos que escribir nuevo contenido nosotros mismos. Si necesita un trozo de contenido, le recomiendo el excelente generador
Fillerama.io , que
corta texto de algunas de mis películas y programas de TV favoritos.
Si está interesado en probar el servidor usted mismo, puede iniciarlo con el siguiente comando:

Después de que el servidor se inicia y nos dice que funciona en el puerto 3333, así como que está conectado a MongoDB, puede abrir
Postman y probar nuestras rutas allí. En cuanto a las opciones GET, simplemente puede insertar la ruta y hacer clic en "Enviar". En el caso de POST, deberá seleccionar "Cuerpo" y completar los campos para el encabezado y el contenido principal.
Nota lateral del cliente
Ahora que hemos configurado y lanzado nuestro servidor, podemos comenzar a trabajar en el cliente con el que interactuarán nuestros usuarios. El cliente se escribirá en React.js, y esto se puede hacer de varias maneras diferentes.
El primero es agregar todas las bibliotecas necesarias para el lado del cliente (react, react-dom, react-router, etc.) al mismo archivo
package.json
donde escribimos las bibliotecas del servidor. En este proyecto, hice exactamente eso, pero debo decir que no creo que esta opción sea óptima. Creo que a medida que nuestro proyecto crezca, la base del código se volverá cada vez más confusa, y si usa solo este método, trabajar con él se volverá más complicado en el futuro. Preferí esta ruta en la aplicación descrita precisamente porque lo sé con certeza: no crecerá y no cambiará en absoluto. Esta aplicación está escrita únicamente con fines de demostración.
El segundo y (en mi opinión) un enfoque más óptimo es crear un repositorio separado para el lado del servidor y uno separado para el cliente. Como antes, podemos clonar fácilmente el repositorio de la parte del cliente en el directorio con nuestro proyecto sin ningún problema, solo necesitamos asegurarnos de que la parte del cliente esté listada en nuestro archivo
.gitignore
. Por ejemplo, en la estructura de archivos para esta aplicación hay un directorio de
client
, donde se encuentra todo el código de pieza del cliente. Podríamos llevarlo a un repositorio completamente separado y luego simplemente agregar la siguiente entrada al archivo
.gitignore
de nuestro repositorio con el lado del servidor:

Al agregar la carpeta del
client
al archivo
.gitignore
, garantizamos que el sistema no percibirá esta carpeta como el segundo repositorio en el proyecto. Además, este enfoque facilita el trabajo de rediseño o reemplazo de la parte del cliente, ya que la parte del servidor no se ve afectada en absoluto.
Cómo exactamente se diseñará su aplicación de pila completa depende totalmente de usted. Simplemente me parece que si mantiene repositorios separados para las partes del cliente y el servidor, la estructura de la aplicación será un poco más precisa.
Creamos una parte de cliente en React.js
Ahora, habiendo entendido la organización del proyecto, hablemos, en realidad, sobre el código del cliente. A continuación se muestra mi archivo
app.js
para una aplicación en React.js, y no insertaré código para cada componente en esta publicación, solo dejo un
enlace al repositorio y explicaré qué hace cada uno de los componentes React.
Y así es como se verá la captura de pantalla de la página principal de nuestra aplicación:

Como puede ver,
app.js
absolutamente nada complicado. Hay un <Router> que le permite configurar rutas en React.js que muestran varios componentes en función de su URL. Estos son los otros componentes que se utilizarán en nuestra aplicación React.js:
- Encabezado : la barra de navegación ubicada en la parte superior de la pantalla
- Índice : enumera las entradas de blog disponibles
- Nuevo : el formulario a través del cual el usuario puede crear una nueva publicación
- Individual : muestra una entrada de blog específica en función de su
id
- Editar : el formulario a través del cual el usuario puede actualizar la entrada de blog encontrada por
id
Usamos Axios para hacer llamadas http a los terminales API, y luego usamos React.js para mostrar los datos como queramos. En esta publicación, daré el código Index.js para que quede más claro cómo funciona todo junto.

En el código anterior, un componente de clase está involucrado, lo que nos permite usar métodos de estado y ciclo de vida. Esto es necesario porque las llamadas de Axios deben realizarse en el método del ciclo de vida del
componentDidMount()
. Cabe señalar que recibí un error de CORS al intentar hacer llamadas a mi API local. Para resolver este problema, agregué varios encabezados al archivo server.js en mi servidor Express, y funcionó. Este código se observa en los comentarios en el archivo server.js.
Asegurémonos de que los robots de búsqueda lean nuestra aplicación React.js normalmente.Para finalizar, me gustaría hablar brevemente sobre el renderizado. Si inicia nuestro sitio y va directamente a alguna publicación de blog, puede haber algunos problemas con la visualización del contenido. En este caso, navegar por el sitio será inconveniente no solo para los usuarios, sino también para buscar robots que indexen contenido. Para solucionar este problema, recomiendo usar herramientas como Gatsby js o Next js. Estas dos soluciones son diferentes entre sí, pero ambas pueden ser útiles, según lo que necesite exactamente.
Gatsby js es un generador de sitio estático. Puede escribir un sitio en React.js, y luego Gatsby lo convertirá en archivos estáticos durante la compilación, lo que hará que el sitio sea súper rápido. Gatsby viene con muchos complementos útiles que hacen que la herramienta sea casi universal. Por cierto, ¡mi sitio se creó con Gatsby.js! Como los archivos estáticos se crean durante el ensamblaje, el sitio debe reconstruirse cada vez que cambie el contenido original.
Next.js , a su vez, es un componente del servidor para mostrar sitios React.js. Se incorporan muchas características útiles, en particular, enrutamiento, división de código, componentes diseñados y mucho más. La representación del servidor significa que los datos se actualizarán automáticamente, como se hace en el servidor, pero, antes de mostrarse en la ventana del navegador, tendrá lugar la etapa de representación. Es por eso que no debería haber ningún problema con la visualización de datos al usuario, y los robots de búsqueda también harán su trabajo sin problemas.
Hay muchas otras soluciones de este tipo, pero escuché mucho sobre estas dos, y cuando trabajé en este proyecto las usé. Ambos están excelentemente documentados, por lo que es fácil lidiar rápidamente con ambos y comenzar a trabajar.
Reflexiones finales sobre la pila MERN
Esperemos que este artículo te haya ayudado con un poco más de precisión sobre cómo funciona la pila MERN. En él, solo tomamos MongoDB, Express.js y Node.js y creamos a partir de ellos un servidor que ya proporciona terminales API a través de los cuales nuestra aplicación React.js puede acceder a los datos. Así que ahora entiendes mucho, ¡es hora de hacer grandes cosas!