
Hola Habr! Les presento la traducci贸n adaptada del primer cap铆tulo de "
Node.js Best Practices " de Yoni Goldberg. Una selecci贸n de recomendaciones en Node.js se publica en github, tiene casi 30 toneladas de estrellas, pero hasta ahora no se ha mencionado en Habr茅. Supongo que esta informaci贸n ser谩 煤til, al menos para principiantes.
1. Consejos de estructura del proyecto
1.1 Estructura tu proyecto por componente
El peor error de las aplicaciones grandes es la arquitectura monol铆tica en forma de una gran base de c贸digo con una gran cantidad de dependencias (c贸digo de espagueti), esta estructura ralentiza enormemente el desarrollo, especialmente la introducci贸n de nuevas funciones. Consejo: separe su c贸digo en componentes separados, para cada componente, seleccione su propia carpeta para los m贸dulos de componentes. Es importante que cada m贸dulo siga siendo peque帽o y simple. En la secci贸n "Detalles", puede ver ejemplos de la estructura correcta de los proyectos.
De lo contrario: ser谩 dif铆cil para los desarrolladores desarrollar el producto: agregar nuevas funcionalidades y realizar cambios en el c贸digo ser谩 lento y tendr谩 una alta probabilidad de romper otros componentes dependientes. Se cree que si las unidades de negocio no est谩n divididas, puede haber problemas con el escalado de la aplicaci贸n.
DetallesExplicaci贸n de un p谩rrafoPara aplicaciones de tama帽o mediano y superior, los monolitos son realmente malos: un programa grande con muchas dependencias es simplemente dif铆cil de entender y, a menudo, conduce a un c贸digo de espagueti. Incluso los programadores experimentados que saben c贸mo "preparar los m贸dulos" adecuadamente gastan mucho esfuerzo en el dise帽o arquitect贸nico y tratan de evaluar cuidadosamente las consecuencias de cada cambio en las relaciones entre los objetos. La mejor opci贸n es una arquitectura basada en un conjunto de programas de componentes peque帽os: divida el programa en componentes separados que no compartan sus archivos con nadie, cada componente debe consistir en una peque帽a cantidad de m贸dulos (por ejemplo, m贸dulos: API, servicio, acceso a la base de datos, pruebas etc.), de modo que la estructura y composici贸n del componente son obvias. Algunos pueden llamar a esta arquitectura "microservicio", pero es importante comprender que los microservicios no son una especificaci贸n que debe seguir, sino m谩s bien un conjunto de algunos principios. A petici贸n suya, puede adoptar tanto estos principios individuales como todos los principios de la arquitectura de microservicios. Ambos m茅todos son buenos si mantiene baja la complejidad del c贸digo.
Lo menos que tiene que hacer es definir los l铆mites entre los componentes: asignar una carpeta en la ra铆z de su proyecto para cada uno de ellos y hacerlos independientes. El acceso a la funcionalidad del componente debe implementarse solo a trav茅s de una interfaz p煤blica o API. Esta es la base para mantener la simplicidad de sus componentes, evitar el "infierno de dependencias" y permitir que su aplicaci贸n se convierta en un microservicio completo.
Cita del blog: "Escalar requiere escalar toda la aplicaci贸n"Del blog MartinFowler.com
Las aplicaciones monol铆ticas pueden ser exitosas, pero las personas se sienten cada vez m谩s frustradas con ellas, especialmente cuando piensan en implementarse en la nube. Cualquier cambio, incluso peque帽o, en la aplicaci贸n requiere el ensamblaje y la redistribuci贸n de todo el monolito. A menudo es dif铆cil mantener constantemente una buena estructura modular en la que los cambios en un m贸dulo no afecten a otros. El escalado requiere escalar toda la aplicaci贸n, y no solo sus partes individuales, por supuesto, este enfoque requiere m谩s esfuerzo.
Cita del blog: "驴De qu茅 habla la arquitectura de su aplicaci贸n?"Del blog de
t铆o-bob... si ha estado en la biblioteca, entonces representa su arquitectura: la entrada principal, los escritorios de recepci贸n, las salas de lectura, las salas de conferencias y muchos salones con estanter铆as. La arquitectura misma dir谩: este edificio es una biblioteca.
Entonces, 驴de qu茅 est谩 hablando la arquitectura de su aplicaci贸n? Cuando miras la estructura de directorios de nivel superior y los archivos de m贸dulos en ellos, dicen: Soy una tienda en l铆nea, soy contador, soy un sistema de gesti贸n de producci贸n. 驴O est谩n gritando: soy Rails, soy Spring / Hibernate, soy ASP?
(Nota del traductor, Rails, Spring / Hibernate, ASP son frameworks y tecnolog铆as web).
Estructura adecuada del proyecto con componentes aut贸nomos.
Estructura de proyecto incorrecta con agrupaci贸n de archivos por prop贸sito
1.2 Separe las capas de sus componentes y no las mezcle con la estructura de datos Express
Cada uno de sus componentes debe tener "capas", por ejemplo, para trabajar con la web, la l贸gica de negocios, el acceso a la base de datos, estas capas deben tener su propio formato de datos no mezclado con el formato de datos de las bibliotecas de terceros. Esto no solo separa claramente los problemas, sino que tambi茅n facilita enormemente la verificaci贸n y prueba del sistema. A menudo, los desarrolladores de API mezclan capas pasando objetos de capa web Express (como req, res) a la l贸gica de negocios y la capa de datos; esto hace que su aplicaci贸n sea dependiente y est茅 fuertemente conectada con Express.
De lo contrario: para una aplicaci贸n en la que se mezclan objetos de capa, es m谩s dif铆cil proporcionar pruebas de c贸digo, organizaci贸n de tareas CRON y otras llamadas no Express.
DetallesDivida el c贸digo del componente en capas: web, servicios y DAL
La otra cara es mezclar capas en una animaci贸n GIF
1.3 Envuelva sus utilidades b谩sicas en paquetes npm
En una aplicaci贸n grande que consta de varios servicios con sus propios repositorios, las utilidades universales como un registrador, cifrado, etc., deben envolverse con su propio c贸digo y presentarse como paquetes privados npm. Esto le permite compartirlos entre varias bases de c贸digo y proyectos.
De lo contrario: debe inventar su propia bicicleta para compartir este c贸digo entre bases de c贸digos separadas.
DetallesExplicaci贸n de un p谩rrafoTan pronto como el proyecto comience a crecer y tenga diferentes componentes en diferentes servidores que utilicen las mismas utilidades, debe comenzar a administrar las dependencias. 驴C贸mo puedo permitir que varios componentes lo usen sin duplicar el c贸digo de su utilidad entre repositorios? Hay una herramienta especial para esto, y se llama npm ... Comience envolviendo paquetes de utilidades de terceros con su propio c贸digo para que pueda reemplazarlo f谩cilmente en el futuro y publique este c贸digo como un paquete privado npm. Ahora toda su base de c贸digo puede importar el c贸digo de utilidades y usar todas las funciones de administraci贸n de dependencias npm. Recuerde que existen las siguientes formas de publicar paquetes npm para uso personal sin abrirlos para acceso p煤blico:
m贸dulos privados , un
registro privado o
paquetes npm locales .
Compartir sus propias utilidades compartidas en diferentes entornos.
1.4 Separe Express en "aplicaci贸n" y "servidor"
Evite el desagradable h谩bito de definir una aplicaci贸n Express completa en un archivo enorme, divida su c贸digo 'Express' en al menos dos archivos: una declaraci贸n API (app.js) y un c贸digo de servidor www. Para una estructura a煤n mejor, coloque una declaraci贸n de API en los m贸dulos componentes.
De lo contrario: su API solo estar谩 disponible para realizar pruebas a trav茅s de llamadas HTTP (que es m谩s lenta y mucho m谩s dif铆cil generar informes de cobertura). A煤n as铆, supongo, no es muy divertido trabajar con cientos de l铆neas de c贸digo en un archivo.
DetallesExplicaci贸n de un p谩rrafoRecomendamos utilizar el generador de aplicaciones Express y su enfoque para crear la base de datos de la aplicaci贸n: la declaraci贸n de API est谩 separada de la configuraci贸n del servidor (datos de puerto, protocolo, etc.). Esto le permite probar la API sin realizar llamadas de red, lo que acelera las pruebas y facilita la obtenci贸n de m茅tricas de cobertura de c贸digo. Tambi茅n le permite implementar de manera flexible la misma API para diferentes configuraciones de red del servidor. Como beneficio adicional, tambi茅n obtiene una mejor separaci贸n de responsabilidades y un c贸digo m谩s limpio.
C贸digo de muestra: declaraci贸n API, debe estar en app.jsvar app = express(); app.use(bodyParser.json()); app.use("/api/events", events.API); app.use("/api/forms", forms);
Ejemplo de c贸digo: los par谩metros de red del servidor deben estar en / bin / www var app = require('../app'); var http = require('http'); var port = normalizePort(process.env.PORT || '3000'); app.set('port', port); var server = http.createServer(app);
Ejemplo: probar nuestra API usando supertest (un paquete de prueba popular) const app = express(); app.get('/user', function(req, res) { res.status(200).json({ name: 'tobi' }); }); request(app) .get('/user') .expect('Content-Type', /json/) .expect('Content-Length', '15') .expect(200) .end(function(err, res) { if (err) throw err; });
1.5 Use una configuraci贸n jer谩rquica segura basada en variables de entorno
Una configuraci贸n ideal deber铆a proporcionar:
(1) lectura de claves tanto del archivo de configuraci贸n como de las variables de entorno,
(2) mantener secretos fuera del c贸digo del repositorio,
(3) estructura de datos jer谩rquica (en lugar de plana) del archivo de configuraci贸n para facilitar el trabajo con la configuraci贸n.
Hay varios paquetes que pueden ayudar a implementar estos puntos, como: rc, nconf y config.
De lo contrario: el incumplimiento de estos requisitos de configuraci贸n conducir谩 a la interrupci贸n del trabajo tanto de un desarrollador individual como de todo el equipo.
DetallesExplicaci贸n de un p谩rrafoCuando se trata de ajustes de configuraci贸n, muchas cosas pueden ser molestas y ralentizarse:
1. Establecer todos los par谩metros usando variables de entorno se vuelve muy tedioso si necesita ingresar m谩s de 100 claves (en lugar de simplemente arreglarlas en el archivo de configuraci贸n), sin embargo, si la configuraci贸n se especificar谩 solo en los archivos de configuraci贸n, esto puede ser inconveniente para DevOps. Una soluci贸n de configuraci贸n confiable debe combinar ambos m茅todos: tanto los archivos de configuraci贸n como las anulaciones de par谩metros de las variables de entorno.
2. Si el archivo de configuraci贸n es JSON "plano" (es decir, todas las claves se escriben como una sola lista), entonces con un aumento en el n煤mero de configuraciones ser谩 dif铆cil trabajar con 茅l. Este problema se puede resolver formando estructuras anidadas que contienen grupos de claves de acuerdo con las secciones de configuraci贸n, es decir organice una estructura de datos JSON jer谩rquica (vea el ejemplo a continuaci贸n). Hay bibliotecas que le permiten almacenar esta configuraci贸n en varios archivos y combinar los datos de ellos en tiempo de ejecuci贸n.
3. No se recomienda almacenar informaci贸n confidencial (como la contrase帽a de una base de datos) en los archivos de configuraci贸n, pero no existe una soluci贸n definitiva y conveniente sobre d贸nde y c贸mo almacenar dicha informaci贸n. Algunas bibliotecas de configuraci贸n le permiten cifrar archivos de configuraci贸n, otras cifran estas entradas durante las confirmaciones de git, o puede guardar par谩metros secretos en archivos y establecer sus valores durante la implementaci贸n a trav茅s de variables de entorno.
4. Algunos escenarios de configuraci贸n avanzada requieren que ingrese las claves a trav茅s de la l铆nea de comando (vargs) o que sincronice los datos de configuraci贸n a trav茅s de un cach茅 centralizado como Redis para que varios servidores usen los mismos datos.
Existen bibliotecas npm que lo ayudar谩n con la implementaci贸n de la mayor铆a de estas recomendaciones. Le recomendamos que eche un vistazo a las siguientes bibliotecas:
rc ,
nconf y
config .
Ejemplo de c贸digo: la estructura jer谩rquica ayuda a encontrar registros y trabajar con archivos de configuraci贸n voluminosos
{ // Customer module configs "Customer": { "dbConfig": { "host": "localhost", "port": 5984, "dbName": "customers" }, "credit": { "initialLimit": 100, // Set low for development "initialDays": 1 } } }
(Nota del traductor, los comentarios no se pueden usar en el archivo JSON cl谩sico. El ejemplo anterior se toma de la documentaci贸n de la biblioteca de configuraci贸n, que agrega funcionalidad para borrar previamente los archivos JSON de los comentarios. Por lo tanto, el ejemplo funciona bastante, sin embargo, las linternas como ESLint con la configuraci贸n predeterminada pueden "Jurar" en un formato similar).
Ep铆logo del traductor:
- La descripci贸n del proyecto dice que la traducci贸n al ruso ya se ha lanzado, pero no encontr茅 esta traducci贸n all铆, as铆 que tom茅 el art铆culo.
- Si la traducci贸n le parece muy breve, intente expandir la informaci贸n detallada en cada secci贸n.
- Lamento que las ilustraciones no hayan sido traducidas.