---
title: NestJS - Framework en Typescript
date: "2020-02-12T05:05:05.505Z"
template: "post"
draft: false
slug: "nestjs-framework-typescript"
category: "Typescript"
tags:
  - "NestJS"
  - "Typescript"
  - "Javascript"
description: "Découvrez les qualités de ce framework Typescript et apprenez à l'intégrer dans une image Docker minimale prête pour la production."
socialImage: "/media/nest.png"
---

![NestJS](/media/nest.png)

## Framework Backend Typescript

[NestJS](https://nestjs.com/) est un framework Typescript dont la
philosophie emprunte beaucoup à Angular.

Cela lui permet de proposer une architecture plus modulaire et de produire
des projets plus maintenables, extensibles et robustes qu'avec
un développement `NodeJS` lambda.

Par rapport à Angular, il est complètement agnostique concernant le front,
il est tout à fait possible d'utiliser `NestJS` pour bâtir une API,
un front en `React` ou même une application CLI.

Si vous ajoutez à cela de 
[très bonnes performances](https://github.com/nestjs/nest/blob/master/benchmarks/all_output.txt)
et une
[popularité grandissante](https://risingstars.js.org/2019/en/#section-nodejs-framework),
vous ne pouvez faire qu'un très bon choix en adoptant NestJs... :)

## NestJS et Docker

On part du `Hello World` qu'on installe de la façon suivante :

```bash
npm i -g @nestjs/cli
nest new app
```

On ajoute ensuite le `Dockerfile` suivant :

```Dockerfile
FROM node:12-alpine

WORKDIR /app

COPY ./app .

RUN yarn; \
    yarn build

CMD ["yarn", "start:prod"]
```

Et le fichier `.dockerignore` suivant :

```.dockerignore
/app/node_modules
/app/dist
```

> Cela permet d'éviter de mettre ces *gros* dossiers dans le contexte Docker
> et de les copier dans l'image.

## Un problème de poids

L'image se contruit et se lance correctement :

```bash
docker build . -t nestjs
docker run --rm -it -p 3000:3000 nestjs
```

Par contre, l'image pèse `400 Mo` !!! Pour un simple `Hello World` ?

![Les nodes modules pèsent lourd](/media/node_modules.png)

## L'explication

L'image contient toutes les `devDepencies` et avec `Typescript`,
elles pèsent lourd (les @types, le compilateur ...)

La solution consiste à construire l'image Docker en 2 étapes :

* la première pour compiler le `Typescript`.
* la seconde pour installer les dépendences de production et servir le build.

On utilise pour cela le mécanisme du
[multistage build](https://docs.docker.com/develop/develop-images/multistage-build/)
de Docker.

```Dockerfile
FROM node:12-alpine AS builder

WORKDIR /app

RUN npm install -g @nestjs/cli

COPY ./app /app

RUN yarn; \
  yarn build

FROM node:12-alpine

ENV NODE_ENV production

WORKDIR /app

COPY --from=builder /app/package.json .
COPY --from=builder /app/yarn.lock .
COPY --from=builder /app/dist ./dist

RUN yarn

CMD ["yarn", "start:prod"]
```

L'image finale ne contient donc que le `dist` et les dépendances de production.

Le résultat : une image de ... `264 Mo` !! Mieux, mais encore très décevant ...

## Supprimer le cache

Voici les tailles de chaque élément de l'image Docker :

* l'image de base `node:12-alpine` : 85Mo
* le répertoire `node_modules` : 35Mo
* le répertoire `dist` : < 1Mo

Le reste ? En fait, il s'agit du
[cache de yarn](https://classic.yarnpkg.com/en/docs/cli/cache/)
qui peut être supprimé dans la dernière commande `RUN` du `Dockerfile`.

```Dockerfile
RUN yarn; \
    yarn cache clean

CMD ["yarn", "start:prod"]
```

Enfin, nous obtenons une image d'une taille raisonnable : `100Mo` tout rond.

Voilà vous pouvez maintenant utiliser `NestJS` dans vos micro-services hébergés
sur Kubernetes !




