Nouveau : Datasets open source gratuits disponibles !Decouvrir →
Intermediaire 25 min NestJS

Deployer NestJS sur Vercel

Pourquoi Déployer NestJS sur Vercel ?

Dans un monde où le développement moderne repose sur la rapidité et l'efficacité, le déploiement rapide de nos applications devient une nécessité incontournable. Les outils comme Vercel offrent des avantages importants pour les développeurs qui cherchent à déployer leurs applications NestJS avec une facilité et une performance optimales.

Un cas d'usage concret est que vous ayez un service de gestion de tâches en cours de développement. Vous souhaiteriez voir votre application en production pour tester sa fiabilité et sa scalabilité, sans avoir à passer par des étapes complexes de déploiement traditionnel. Vercel facilite ce processus, permettant une mise à jour instantanée et sécurisée de votre application NestJS.

Prerequis

  • Connaissance approfondie de la technologie NestJS
  • Compréhension des concepts de routes, controllers, services et modules en NestJS
  • Familiarité avec les outils de gestion de paquets npm et yarn
  • Un compte Vercel
  • Un environnement local configuré (Node.js, npm)
  • Connaissance de la ligne de commande

Concepts Fondamentaux

1. Projets NestJS

Un projet NestJS est une application Node.js qui utilise le framework NestJS. Il comprend généralement des controllers, des services et des modules pour structurer l'application.

// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

2. Controllers

Les controllers gèrent les requêtes HTTP et renvoient les réponses.

// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

3. Services

Les services contiennent la logique métier de l'application.

// app.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

Mise en Pratique : Projet Fil Rouge

Nous allons créer un simple API de blog pour illustrer le déploiement sur Vercel. L'API devra permettre de créer, lire, mettre à jour et supprimer des articles.

Étape 1 : Initialiser le projet NestJS

Créer un nouveau projet NestJS :

nest new blog-api
cd blog-api

Étape 2 : Créer les entités et services

Créez une entité Article et un service associé.

// src/article/article.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity()
export class Article {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @Column()
  content: string;
}
typescript
// src/article/article.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Article } from './article.entity';

@Injectable()
export class ArticleService {
  constructor(
    @InjectRepository(Article)
    private readonly articleRepository: Repository<Article>,
  ) {}

  findAll(): Promise<Article[]> {
    return this.articleRepository.find();
  }

  findOne(id: number): Promise<Article> {
    return this.articleRepository.findOne(id);
  }

  async remove(id: number): Promise<void> {
    await this.articleRepository.delete(id);
  }

  async create(article: Article): Promise<Article> {
    return this.articleRepository.save(article);
  }
}

Étape 3 : Créer les contrôleurs

Créez des contrôleurs pour gérer les requêtes HTTP.

// src/article/article.controller.ts
import { Controller, Get, Post, Body, Param, Delete } from '@nestjs/common';
import { ArticleService } from './article.service';
import { Article } from './article.entity';

@Controller('articles')
export class ArticleController {
  constructor(private readonly articleService: ArticleService) {}

  @Post()
  async create(@Body() article: Article): Promise<Article> {
    return this.articleService.create(article);
  }

  @Get()
  async findAll(): Promise<Article[]> {
    return this.articleService.findAll();
  }

  @Get(':id')
  async findOne(@Param('id') id: number): Promise<Article> {
    return this.articleService.findOne(id);
  }

  @Delete(':id')
  async remove(@Param('id') id: number): Promise<void> {
    await this.articleService.remove(id);
  }
}

Étape 4 : Configurer le fichier app.module.ts

Incluez le module de l'article dans le module principal.

// src/app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ArticleModule } from './article/article.module';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'sqlite',
      database: 'db.sqlite',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
    ArticleModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Étape 5 : Configurer le fichier article.module.ts

Définissez le module pour l'article.

// src/article/article.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ArticleController } from './article.controller';
import { ArticleService } from './article.service';
import { Article } from './article.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Article])],
  controllers: [ArticleController],
  providers: [ArticleService],
})
export class ArticleModule {}

Étape 6 : Créer un fichier vercel.json pour le déploiement

Créez un fichier vercel.json à la racine de votre projet.

{
  "version": 2,
  "frameworks": [
    {
      "type": "nextjs"
    }
  ],
  "builds": [
    {
      "src": "main.ts",
      "use": "@vercel/node"
    }
  ]
}

Étape 7 : Déploiement sur Vercel

Connectez votre compte Vercel et importez votre projet. Sélectionnez le déploiement manuel ou utilisez un dépôt Git pour le déclencher automatiquement.

Erreurs Fréquentes et Debugging

Erreur 1 : TypeError: Cannot read property 'find' of undefined

Le problème peut se produire si la table n'est pas correctement créée dans la base de données SQLite.

// src/app.module.ts
TypeOrmModule.forRoot({
  type: 'sqlite',
  database: 'db.sqlite',
  entities: [__dirname + '/**/*.entity{.ts,.js}'],
  synchronize: true, // Ajustez cette ligne si vous rencontrez des problèmes avec la synchronisation.
})

Erreur 2 : Cannot find module './app.module'

Le problème peut se produire si le chemin du fichier est incorrect.

npm run start:dev

Erreur 3 : Missing required peer dependency 'typescript@^4.0.0'

Ce message indique que vous n'avez pas installé la version requise de TypeScript.

npm install typescript@^4.0.0 --save-dev

Pour Aller Plus Loin

1. Intégration avec Docker

Utilisez Docker pour containeriser votre application NestJS.

## Dockerfile
FROM node:14

WORKDIR /usr/src/app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "run", "start"]

2. Utilisation de Swagger pour la documentation API

Ajoutez Swagger pour générer automatiquement la documentation de votre API.

npm install @nestjs/swagger swagger-ui-express --save

Créez un fichier main.ts pour configurer Swagger.

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Blog API')
    .setDescription('API pour le blog')
    .setVersion('1.0')
    .addTag('articles')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();

3. Optimisation des performances

Optimisez les performances de votre application en utilisant le cache et la mise en cache des données.

// src/app.module.ts
TypeOrmModule.forRoot({
  type: 'sqlite',
  database: 'db.sqlite',
  entities: [__dirname + '/**/*.entity{.ts,.js}'],
  synchronize: true,
  caching: true, // Activer le cache pour les requêtes TypeORM.
})

Défi Pratique

Créez un service de scraping pour extraire des données d'une page web et les stocker dans votre base de données.

// src/scraping/scraping.service.ts
import { Injectable } from '@nestjs/common';
import axios from 'axios';

@Injectable()
export class ScrapingService {
  async scrape(url: string): Promise<string> {
    const response = await axios.get(url);
    return response.data;
  }
}

Ajoutez une route pour déclencher le scraping.

// src/scraping/scraping.controller.ts
import { Controller, Get, Param } from '@nestjs/common';
import { ScrapingService } from './scraping.service';

@Controller('scrape')
export class ScrapingController {
  constructor(private readonly scrapingService: ScrapingService) {}

  @Get(':url')
  async scrape(@Param('url') url: string): Promise<string> {
    return this.scrapingService.scrape(url);
  }
}

Ajoutez le module et le service au fichier app.module.ts.

// src/app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ArticleModule } from './article/article.module';
import { ScrapingModule } from './scraping/scraping.module';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'sqlite',
      database: 'db.sqlite',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
    ArticleModule,
    ScrapingModule, // Ajoutez le module du scraping.
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Ajoutez une nouvelle entité et un service pour stocker les données scrapées.

// src/scraped-data/scraped-data.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity()
export class ScrapedData {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('text')
  data: string;
}
typescript
// src/scraped-data/scraped-data.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ScrapedData } from './scraped-data.entity';

@Injectable()
export class ScrapedDataService {
  constructor(
    @InjectRepository(ScrapedData)
    private readonly scrapedDataRepository: Repository<ScrapedData>,
  ) {}

  async save(data: string): Promise<void> {
    const newData = this.scrapedDataRepository.create({ data });
    await this.scrapedDataRepository.save(newData);
  }
}
typescript
// src/scraped-data/scraped-data.controller.ts
import { Controller, Get, Param } from '@nestjs/common';
import { ScrapingService } from '../scraping/scraping.service';
import { ScrapedDataService } from './scraped-data.service';

@Controller('scraped-data')
export class ScrapedDataController {
  constructor(
    private readonly scrapingService: ScrapingService,
    private readonly scrapedDataService: ScrapedDataService,
  ) {}

  @Get(':url')
  async scrapeAndSave(@Param('url') url: string): Promise<void> {
    const data = await this.scrapingService.scrape(url);
    await this.scrapedDataService.save(data);
  }
}

Ajoutez le module et le service au fichier app.module.ts.

// src/app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ArticleModule } from './article/article.module';
import { ScrapingModule } from './scraping/scraping.module';
import { ScrapedDataModule } from './scraped-data/scraped-data.module';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'sqlite',
      database: 'db.sqlite',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
    ArticleModule,
    ScrapingModule,
    ScrapedDataModule, // Ajoutez le module du scraping des données.
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Ce tutoriel a couvert les concepts de base pour déployer une application NestJS sur Vercel. Vous avez créé un projet complet et réalisé un déploiement efficace. N'oubliez pas d'explorer davantage les fonctionnalités de Vercel et de NestJS pour améliorer votre développement et votre production continue.

Besoin d'aide sur NestJS ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment installer les dépendances nécessaires pour le déploiement de NestJS sur Vercel ?
Pour installer les dépendances nécessaires, exécutez la commande `npm install` dans votre terminal. Assurez-vous que Node.js et npm sont installés sur votre machine.
Quelles configurations spécifiques doivent-je faire dans mon projet NestJS pour qu'il fonctionne correctement sur Vercel ?
Il est recommandé de créer un fichier `vercel.json` à la racine de votre projet et d'y inclure des instructions spécifiques pour Vercel, comme le nom du runtime (nodejs) et les variables d'environnement nécessaires.
Comment puis-je déployer mon application NestJS sur Vercel ?
Pour déployer votre application, connectez Vercel à votre compte GitHub ou GitLab si vous utilisez un système de contrôle de version. Sélectionnez le dépôt contenant votre projet NestJS et suivez les instructions pour configurer et déployer l'application.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.