This is an old revision of the document!
Table of Contents
Configuración de un proyecto
Convenciones de código / Guias de estilo
No existe ninguna guia de estilo oficial para desarrollar con lenguaje Javascript. Diferentes organizaciones o compañias elaboran las suyas propias para uso interno o bien para extender un buen estilo entre desarrolladores.
Os dejo aqui un par de guias de estilo a modo de ejemplo:
Contenido generado
Son todos aquellos ficheros o carpetas que generan las herramientas que empleamos para desarrollar
- Por parte del Sistema Operativo:
- Sistemas MacOs:
.DS_Store
- Por parte del IDE:
- IDEs de Jetbrains:
.idea - Visual Studio Code:
.vscode
- Por parte del framework:
- Node.js/npm:
node_modulesypackage-lock.json
- Sistemas de Control de Versiones:
- Git:
.gitcontiene toda la información necesaria del repositorio en el equipo local
Representan todo lo que tendremos que añadir a nuestro fichero .gitignore para que no sea incluido en el repositorio del proyecto
Mantener estilos y convenciones entre diferentes IDEs: EditorConfig
- .editorconfig
[*.js] indent_style = space indent_size = 4
Reinicio automático (hot reload)
nodemon es una herramienta que permite que nuestra aplicación nodejs se reinicie automáticamente cada vez que detecta un cambio en el código. De esa manera podemos evitar tener que estar continuamente parando y arrancándola.
Primero tendremos que instalar nodemon de forma global (de forma que podamos ejecutarlo como un nuevo comando de nuestro equipo):
santi@localhost:$ npm install -g nodemon
A partir de entonces, si tenemos bien configurado el script start de nuestro proyecto en el fichero package.json, podremos lanzar el proyecto simplemente ejecutando nodemon y éste monitorizará nuestro código en busca de cambios para reiniciarlo automáticamente. Asi podemos centrarnos simplemente en escribir código y comprobar si éste funciona correctamente:
santi@localhost:$ nodemon [nodemon] 3.1.7 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): *.* [nodemon] watching extensions: js,mjs,cjs,json [nodemon] starting `node src/app.js` Iniciando el backend en el puerto 8080
Cómo gestionar el ciclo de vida de mi proyecto
Qué version del framework elegir
A la hora de definir la configuración del proyecto, podemos también indicar para qué versiones del framework, node en este caso, está preparado para funcionar:
. . . "name": "my-project", "version": "1.0.0", "engines": { "node": "20.x" . . .
El calendario de releases de cualquier framework puede consultarse en su página web. En el caso de Nodejs, está disponible en https://nodejs.org/en/about/previous-releases
Para saber qué cambios ha habido en una release/version concreta, tendremos que consultar lo que se conoce como Changelog. Por ejemplo, en https://nodejs.org/en/download/archive/v24.21.0 se pueden consultar el de Node v24 junto con otros detalles sobre esa release.
Uso de linters
eslint es una herramienta que funciona como linter. Un linter en una herramienta que realiza un análisis estático de código. Esto es, revisa el código en busca de errores de sintaxis o de estilo, potenciales errores por referencias a variables que no existen o variables que no se utilizan, . . .
Para utilizar eslint, tendremos que incluirlo como dependencia de desarrollo, devDependencies, en nuestro package.json, junto con una serie de plugins:
- package.json
{ "name": "cities-backend", "version": "0.1", "description": "A sample project to learn Node.js", "type": "module", "scripts": { "lint": "eslint .", "lint:fix": "eslint . --fix", "start": "node src/app.js" }, "author": "Santiago Faci", "license": "GPL-2.0-only", "dependencies": { "express": "^4.21.1" }, "devDependencies": { "eslint": "6.4.0", "eslint-config-standard": "14.1.1", "eslint-plugin-import": "2.22.1", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "4.3.1", "eslint-plugin-standard": "4.1.0" } }
El siguiente paso será preparar un fichero de configuración para eslint. En él definiremos las reglas que queremos que nuestro código siga, cuando queremos un error o un warning y cualquier otro parámetro. El siguiente es un ejemplo sencillo de un fichero de configuración que revisará aspectos como habituales como:
- Que el indentado de código sea de 4 espacios
- Que se emplee el punto y coma (semicolon) al final de cada sentencia
- Que no haya puntos y coma adicionales
- Nos avisará de las variables definidas que realmente no se usen
- Nos permitirá usa sentencias como console.log para mostrar mensajes por pantalla (su uso no siempre está recomendado)
- .eslintrc.js
module.exports = { "env": { "node": "true" }, "extends": [ "eslint:recommended" ], "parserOptions": { "ecmaVersion": 2020, "sourceType": "module" }, "rules": { "indent": ["error", 4], "semi": ["error", "always"], "no-extra-semi": "error", "no-unused-vars": "warn", "no-console": "off" } }
npm runt lint ejecutará eslint para llevar a cabo el análisis estático de nuestro código, mostrándonos todos los errores encontrados:
santi@zenbook:$ npm run lint > cities-backend@0.1 lint > eslint . /home/santi/Projects/cities-backend-module-linter/src/app.js 22:21 error Missing semicolon semi 26:1 error Expected indentation of 4 spaces but found 0 indent ✖ 2 problems (2 errors, 0 warnings) 2 errors and 0 warnings potentially fixable with the `--fix` option.
Si queremos que eslint corrija todos los errores que pueda, podemos ejecutar npm run lint:fix que, en nuestro package.json, lanza eslint con el flag –fix que arreglará todo los fallos posibles (en ocasiones hay problemas que tendremos que arreglar a mano)
santi@zenbook:$ npm run lint:fix > cities-backend@0.1 lint > eslint .
Es probable que no todo lo que forma parte del proyecto en un momento determinado deba ser analizado por eslint. Hay mucho contenido generado que querremos ignorar. Para eso podemos indicarlo en el fichero .eslintignore y la herramienta ignorará esos ficheros o carpetas:
- .eslintignore
coverage/ public/ submodules/ toolforge/
Reutilización de código: exportar/importar funciones
Documentación
Siempre que trabajemos en el desarrollo de un proyecto de software tendremos que desarrollar algún tipo de documentación. Esta documentación dependerá del tipo de usuario al que vaya destinado dicho proyecto:
- Manual de usuario: Tendrás que hacer un manual de usuario cuando tu proyecto esté destinado para ser utilizado por usuarios humanos
- Documentación técnica: En ocasiones estarás desarrollando librerías que otros desarrolladores necesitarán usar
- Especificación API: Si desarrollas un backend con el objetivo de desarrollar una API REST, existe una especificación concreta que deberás de seguir, Open API Specification, también conocida como OAS
Como los proyectos que estamos desarrollando son APIs, nos centraremos en la generación de documentación siguiendo la especificación Open API, concretamente para proyectos desarrollados con el framework Node.js
Enfoque API First
Enfoque Code First
Es la metodología tradicional. En este caso, primero se implementa la API en base a los requisitos funcionales y la documentación se generará más adelante (probablemente con alguna librería que permitirá que se integre de cierta manera con el código).
En este enfoque se prioriza la velocidad de implementación. Cabe destacar que, en los últimos años, ha ido ganando protagonismo el otro enfoque, API First, por todas las ventajas que presenta.
Organización de un proyecto
En nuestro caso nos enfocaremos en la organización de un proyecto para el desarrollo de una API REST utilizando el framework de desarrollo de Node.js
En nuestro caso trabajaremos con las siguientes capas:
- route: Se definen las rutas o endpoints disponibles para cada uno de los elementos del modelo de datos
- controller: Se definen las funciones que reciben las peticiones de las rutas definidas en la capa
route - service: Funciones que definen la lógica de aplicación
A continuación desarrollaremos una API completa (CRUD) utilizando una base de datos y con el código organizado correctamente siguiendo el modelo de capas que se ha planteado anteriormente.
Ficheros de configuración
- config.local.yaml
db: host: localhost port: 3306 user: user password: password database: cities service: port: 8080
- config/configuration.js
const yaml = require('js-yaml'); const fs = require('fs'); const yargs = require('yargs/yargs'); const { hideBin } = require('yargs/helpers'); // Lee el fichero de configuración let configFile = 'config.prod.yaml'; const argv = yargs(hideBin(process.argv)).argv; if (argv.config != undefined) { configFile = argv.config; } const config = yaml.load(fs.readFileSync(configFile, 'utf-8')); module.exports = { config };
Dockerizar un entorno de pruebas
https://www.docker.com/products/docker-desktop/
- db/init.sql
CREATE DATABASE cities; GRANT ALL PRIVILEGES ON cities.* TO USER; USE cities; CREATE TABLE cities ( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), population INT, altitude FLOAT, foundation_date DATE, age INT, area INT, density FLOAT, id_country INT ); INSERT INTO cities (name, population, altitude, foundation_date, age, area, density) VALUES ('Zaragoza', 700000, 200, '1000-01-01', 1000, 734734, 2373), ('Madrid', 5000000, 500, '1200-01-01', 800, 344734, 23473);
- docker-compose.dev.yaml
name: cities services: db: image: mariadb:11.3.2 container_name: cities-dev-db environment: MARIADB_USER: user MARIADB_PASSWORD: password MARIADB_DATABASE: cities MARIADB_PORT: 3306 MARIADB_ROOT_PASSWORD: password ports: - "3306:3306" volumes: - ./db:/docker-entrypoint-initdb.d
Automatización con Makefile
https://dev.to/debajit13/make-makefiles-a-modern-developers-guide-to-classic-automation-14hl
- Makefile
start-dev-env: docker compose -f docker-compose.dev.yaml up -d stop-dev-env: docker compose -f docker-compose.dev.yaml down all-test: stop-dev-env start-dev-env sleep 4 npm test .PHONY: all-test start-dev-env stop-dev-env
santi@zenbook:$ make start-dev-env
Licencia del proyecto
Mock API
- db.json
{ "$schema": "./node_modules/json-server/schema.json", "movies": [ { "id": "1", "title": "Spiderman", "views": 100 }, { "id": "2", "title": "Superman", "views": 200 }, { "id": "3", "title": "X-Men", "views": 550 }, { "id": "4", "title": "Batman", "views": 230 } ], "comments": [ { "id": "1", "text": "Que pelicula más buena", "movieId": "1" }, { "id": "2", "text": "Que pelicula más mala", "movieId": "2" }, { "id": "3", "text": "Que pelicula más normal", "movieId": "2" }, { "id": "4", "text": "Que pelicula más alucinante", "movieId": "3" } ] }
santi@zenbook:$ npm install json-server@0.17.4
santi@zenbook:$ npx json-server db.json
© 2024-2026 Santiago Faci

