Este artículo se inspiró en mi propia frustración en la optimización de mi configuración de NodeJS con Typescript y Docker. La mayoría de los procesos y tutoriales conducen a configuraciones que hacen que el desarrollo sea agotador y lento, entre tantas reconstrucciones y reinicios su paciencia se agota y su productividad se agota. Después de mucha investigación, pruebas y estrés, pude armar una configuración ideal!

Es necesario que usted tenga al menos el conocimiento básico de nodo, tipo de ley y docker, no voy a explicar ninguna tecnología en profundidad, si usted tiene alguna pregunta específica estaré encantado de ayudar en los comentarios.

Al final de este tutorial tendrá un entorno de desarrollo NodeJS con Typescript, ts-node-dev, Docker, ESlint con Airbnb Style Guide y Prettier.

Todos los códigos de este tutorial están disponibles en GitHub.

En la primera parte del artículo configuraremos nuestro IDE de código de Visual Studio para el desarrollo, no dude en omitir esta parte si usa otro IDE.

Configuración de VS Code

Primero vamos a crear una carpeta vacía para nuestro proyecto e iniciar vs código en él:

$mkdir node-ts-optimized && code node-ts-optimized/

Extensiones útiles de VS Code

Recomiendo instalar las extensiones enumeradas a continuación, aumentarán su productividad:

Configuración del espacio de trabajo

Dentro del proyecto, si aún no existe, cree una carpeta .vscode y el archivo settings.json. Agregue las siguientes propiedades:

{
  "eslint.autoFixOnSave": true,
  "eslint.validate": [
    "javascript",
    "idioma": "typescript", "autoFix": true,
  ],
  "editor.formatOnSave": true,
  "[javascript]":  {
    "editor.formatOnSave": false,
  },
  "[typescript][javascript]":  {
    "editor.formatOnSave": false,
  }
}

Esto habilita automáticamente el agente automático ESlint y Prettier al guardar un archivo.

Inicio de un proyecto NodeJS

Ahora necesitamos inicializar un proyecto de nodo:

$cd node-ts-optimized && npm init

Dentro del proyecto vamos a crear una carpeta src/, es en ella que vamos a poner todos nuestros archivos .ts de fuentes. Disfrutar y crear un archivo vacío con el nombre index.ts, lo usaremos más adelante.

TypeScript y ts-node-dev

Ahora necesitamos instalar todas las dependencias que necesitaremos para nuestro entorno de desarrollo:

$npm i --save-dev typescript ts-node-dev 

La opción –save-dev instala las dependencias como devDependencies, ya que no serán necesarias ni instaladas en nuestra imagen de Docker de producción.

  • typescript: Lib oficial para compilar nuestros archivos .ts
  • ts-node-dev: habilita REPL para TypeScript, con reinicio automático, que permite que nuestro código TypeScript funcione en tiempo real, sin compilación (piense en nodemon o node-dev, pero para TypeScript).

Cree el archivo tsconfig.json con la configuración del compilador Typescript:

{
  "compilerOptions":
    "target": "ES2020",
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "construir"
  }
}

En el destino vamos a utilizar la versión 2020 de ECMAScript, puede cambiar la versión de acuerdo con las necesidades de su proyecto.

ESLint y Más Bonito

Decidí elegir ESLint como el linter para esta configuración por la sencilla razón de que hubo el anuncio de la discontinuación del proyecto TSLint, aunque lo usé y me gustó en otros proyectos, no vale la pena invertir en una dependencia importante, que ya tiene sus días de vida numerados. Instale ESLint y todas sus dependencias localmente:

$npm i --save-dev eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-airbnb-base eslint-plugin-import eslint-config-prettier eslint-plugin-prettier más bonito

En la raíz del proyecto, cree un archivo .eslintrc.js de configuración de ESLint:

module.exports ?
    analizador: '@typescript-eslint/parser',
    parserOptions:
      sourceType: 'módulo',
      proyecto: './tsconfig.json',
    },
    se extiende: [
      'airbnb-base', // Añadir reglas de la Guía de Estilo Airbnb
      'plugin:@typescript-eslint/recommended', // Añade recomendaciones estándar @typescript-eslint/eslint-plugin
      'prettier/@typescript-eslint', // Añade ajustes más bonitos para evitar conflictos de reglas @typescript-eslint/eslint-plugin
      'plugin:prettier/recommended', // Añade plugin más bonito
    ],
  }

Ahora cree el archivo .prettier.js de configuración de Prettier.js:

module.exports ?
  semi: verdadero,
  trailingComma: 'todos',
  singleQuote: falso,
  printWidth: 120,
  tabWidth: 2,
};

Ahora vamos a agregar un script a nuestro archivo package.json para ejecutar pelusas:

...
"scripts":
  "test": "echo "Error: no especificado test" && exit 1",
  "lint": "eslint --fix ./src/*"
}
...

Este comando básicamente hace que ESLint escanee todos los archivos dentro de therc/carpeta e intente automáticamente solucionar cualquier posible problema. No todos los problemas se solucionan automáticamente, y para ser honesto la gran mayoría de los problemas importantes que tendrá que solucionar manualmente.

Ejecute npm run lint y compruebe que no se debe devolver ningún error.

Si está utilizando VS Code con la configuración de inicio del artículo, estos errores aparecerán resaltados automáticamente en su IDE, y cuando guarde algún archivo ESLint intentará solucionar cualquier problema y Más Bella hará el formato automático.

Desarrollar en Typescript sin compilar todo el tiempo

Si ya has desarrollado con Typescript, probablemente te hayas molestado con todo el proceso de compilación y reinicio de tu aplicación. Hay varias maneras de configurar su entorno para compilar sus archivos .ts y reiniciar su aplicación, aquí nos centraremos en la configuración que me sentí más productiva, utilizando lib ts-node-dev. Esta biblioteca compila Typescript pero comparte esta compilación entre reiniciar la aplicación, lo que significa que podremos tener una recarga automática sin tener que esperar a todo el proceso de compilación. Lib ts-node-dev es una mezcla de otras dos bibliotecas, node-dev con ts-node.

Vamos a crear el script dev que se usará durante el desarrollo:

...
"scripts":
  "test": "echo "Error: no especificado test" && exit 1",
  "lint": "eslint --fix ./src/*",
  "dev": "ts-node-dev --inspect-8181 --respawn --transpileOnly src/index.ts"
}
...
  • --inspect Define el puerto en el que el depurador estará escuchando.
  • --respawn Continúa observando los archivos por cambios incluso si el proceso principal muere.
  • --transpileOnly Deshabilita la comprobación de escritura y la salida de los archivos de definición, promoviendo una transpilación más rápida.

Adición de código real al proyecto

Vamos a añadir un código simple para poder probar nuestra configuración. Instale la dependencia express y su escritura:

$npm i--save express
$npm instalar --save-dev @types/express @types/node

Ahora abra el archivo index.ts y pegue el siguiente código:

importar * como expresar desde "express";

const PORT 8080; Puerto de nuestro servidor web

const app - express(); Creamos una instancia de

Se ha añadido una ruta de prueba
app.get("/hello-world", (req: express. Solicitud, res: express. Respuesta) ?>
  res.json(?
    mensaje: "Hola Mundo",
  });
});

Iniciamos nuestro servidor web
app.listen(PORT, () ? >
  console.log('Aplicación de escucha en el puerto $-PORT-');
});

Ejecute el comando npm run dev, abra el explorador y acceda a http://localhost:8080/hello-world

Probar nuestra nueva configuración

Para probar si nuestra configuración se realizó correctamente, modifiquemos nuestro código original y agreguemos una nueva ruta:

importar * como expresar desde "express";

const PORT 8080; Puerto de nuestro servidor web

const app - express(); Creamos una instancia de

Se ha añadido una ruta de prueba
app.get("/hello-world", (req: express. Solicitud, res: express. Respuesta) ?>
  res.json(?
    mensaje: "Hola Mundo",
  });
});

Se ha añadido una ruta de prueba con parámetros
app.get("/hello-world/:name", (req: express. Solicitud, res: express. Respuesta) ?>
  const - nombre - req.params;
  res.json(?
    mensaje: 'Hola $'nombre'!',
  });
});

Iniciamos nuestro servidor web
app.listen(PORT, () ? >
  console.log('Aplicación de escucha en el puerto $-PORT-');
});

Guarde el archivo y vea cómo sucede la magia, el resultado esperado es que la aplicación identifica nuestra modificación y actualiza el proceso automáticamente. Para validar, vaya a http://localhost:8080/helo-world/henrique:

Dockerizing la aplicación

Vamos a crear el archivo Dockerfile.dev que será la configuración de nuestra imagen de desarrollo:

DESDE nodo:12-alpino

WORKDIR /app

ADD package*.json ./

NPM RUN

Ahora necesitamos crear el archivo docker-compose.yml:

versión: "3.7"

Servicios:
  node-ts-optimized:
    Construir:
      Contexto:.
      dockerfile: Dockerfile.dev
    container_name: ejemplo-web-server
    Volúmenes:
      - ./src:/app/src
    Puertos:
      - "8080:8080"
      - "8181:8181"
    Comando: NPM Run Dev

Vamos a probar nuestro desarrollo iniciando docker compose:

$docker-componer

Repita los pasos del último paso y cambie algunos códigos, compruebe el explorador para ver si se ha iniciado la aplicación y si el código se está actualizando.

Configuración del depurador en VS Code

A medida que estamos desarrollando dentro de nuestro contenedor, necesitamos tener acceso a la depuración remota del nodo, por lo que liberamos el puerto 8181 en la ventana acoplable de composición y también en nuestro script de desarrollo package.json. Vamos a crear un archivo launch.json dentro de nuestra carpeta .vscode y pegar la configuración:

{
  "type": "nodo",
  "request": "adjuntar",
  "name": "Docker ts-node",
  "address": "localhost",
  "port": 8181,
  "localRoot": "$-workspaceFolder",
  "remoteRoot": "/app",
  "protocol": "inspector"
}

Ahora podemos arrancar el depurador. Si está en VS Code, presione F5.

Creación de la imagen de Docker para producción

Finalmente vamos a crear el script de imagen que se implementará en producción, tiene algunas diferencias en la optimización:

DESDE nodo:12-alpino

WORKDIR /home/node/app

Añadir. .

ENV NODE_ENV-producción

RUN ci npm

Nodo USUARIO

EXPOSICIÓN 8080

Cmd[ "node", "build/index.js" ]

Las diferencias entre el archivo Dockerfile.dev y dockerfile son:

  1. Definimos la variable de entorno NODE_ENV para la producción, esto evitará que se instalen las dependencias enumeradas en devDependencies en nuestro package.json.
  2. Para buenas prácticas no usaremos alias de script npm para iniciar nuestra aplicación, esto reduce el número de procesos iniciados y obliga a que las señales de terminación sigterm y SIGINT sean recibidas directamente por el proceso Node en lugar de ser interceptadas por npm: Docker Node – Good Practices.

Conclusión

Aprendimos a configurar un entorno de desarrollo para NodeJS con Typescript, con auto-recarga e linter. Si usted tiene algún consejo para mejorar este ajuste, por favor deje su comentario!

2 2 votos
Nota do Artigo
Subscribe
Notify of
guest

0 Comentários
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x