Accueil / Articles

Mettre en place Prisma 7 avec PostgreSQL dans un projet Node.js TypeScript

Corrigez les erreurs courantes de configuration de Prisma 7 en TypeScript, allant des adresses URL manquantes ou non définies aux problèmes liés à rootDir, et connectez PostgreSQL à l’adaptateur du pilote pg.

Éditeur : REACTAPP.TOP7 min de lecture1666 mots

Sources: I Wasted 4 Hours Setting Up Prisma — Here’s How You Should Set Up Prisma v7

Suivre le guide de démarrage rapide de Prisma dans un projet Node.js classique en TypeScript se solde souvent par une série d’erreurs de compilateur avant même que la moindre requête ne soit exécutée. Les problèmes ne viennent pas de vos modèles ; ils proviennent de la manière dont le compilateur TypeScript, le nouveau fichier de configuration de Prisma et le client généré interagissent avec une structure conventionnelle src/dist. Ce guide explique les trois erreurs auxquelles vous êtes le plus susceptible de faire face, la raison pour laquelle chacune se produit, ainsi qu’une configuration étape par étape avec PostgreSQL qui permet une compilation sans erreur. Prisma 7 a modifié plusieurs paramètres par défaut, il est donc conseillé de consulter la documentation actuelle de Prisma pour vérifier d’éventuels changements depuis la rédaction de ce texte.

Les trois erreurs qui gênent une configuration neuve

Une URL de connexion saisie en tant que chaîne de caractères ou définie comme undefined

Dans prisma.config.ts, l’URL de la base de données est généralement lue à l’aide de process.env.DATABASE_URL. TypeScript définit chaque variable d’environnement comme string | undefined, car rien ne garantit qu’elle soit définie au moment de l’exécution. La configuration attend une simple string, ce qui fait que le compilateur rejette l’affectation.

prisma.config.ts en dehors du répertoire racine

Un projet TypeScript typique définit rootDir sur src et outDir sur dist. Prisma crée le fichier prisma.config.ts dans la racine du projet, et par défaut le compilateur inclut tous les fichiers .ts qu’il trouve. Il se plaint ensuite d’une présence de fichiers en dehors de rootDir au sein du programme. Déplacer la configuration dans src ferait disparaître l’erreur, mais ce n’est pas la bonne solution : src est destiné au code de l’application, tel que les routes, les contrôleurs et les mécanismes d’accès aux données, et non à la configuration des outils.

Un client généré en dehors du répertoire racine

Il en va de même pour le client généré. Si Prisma l’écrit dans generated/prisma au niveau de la racine du projet, le compilateur trouve à nouveau des fichiers TypeScript en dehors de rootDir. Placer le code généré dans src est également une mauvaise option, car il s’agit d’un résultat de compilation issu de prisma generate, et non d’un code source que l’on maintient.

Si ces problèmes ne sont pas résolus, ils empêchent le projet de démarrer. Un effet secondaire tout aussi agaçant est que le JavaScript compilé pour prisma.config.ts peut se retrouver en dehors de dist, encombrant ainsi le répertoire. Corriger les erreurs une par une a tendance à en créer de nouvelles, il est donc préférable de régler l’ensemble de la configuration.

Étape 1 : créer le projet et installer les dépendances

Commencez par un projet TypeScript vide. Installez le compilateur, tsx pour exécuter directement TypeScript, ainsi que les définitions de types de Node, puis générez un tsconfig.json:

npm init
npm install typescript tsx @types/node --save-dev
npx tsc --init

Ensuite, installez Prisma. La CLI et les définitions de types pg sont des dépendances de développement ; le client, l’adaptateur du pilote PostgreSQL, le pilote pg et dotenv sont des dépendances en temps de exécution :

npm install prisma @types/pg --save-dev
npm install @prisma/client @prisma/adapter-pg pg dotenv

Le paquet @prisma/adapter-pg est important ici. Dans Prisma 7, le client communique avec la base de données via un adaptateur de pilote JavaScript, ce qui vous permet de lui transmettre une connexion pg configurée plutôt que de vous fier uniquement à une URL dans le schéma.

Étape 2 : configurer les modules ES et la structure du compilateur

Marquez le paquet comme un module ES dans package.json:

{
  "type": "module"
}

Ensuite, définissez les dossiers de source et de sortie dans tsconfig.json, puis créez le dossier src:

"rootDir": "./src",
"outDir": "./dist",

Étape 3 : initialiser Prisma

Exécutez la CLI une fois (cela affiche simplement les commandes disponibles et confirme que l’installation fonctionne) :

npx prisma

Ensuite, initialisez Prisma pour PostgreSQL :

npx prisma init --datasource-provider postgresql --output ../generated/prisma

Cela crée prisma.config.ts, un dossier prisma contenant schema.prisma, ainsi qu’un fichier .env pour l’URL de la base de données. Le paramètre --output définit l’endroit où le client sera généré ; l’étape 4 reviendra sur ce choix. C’est juste après cette étape que les erreurs décrites ci-dessus apparaissent.

Étape 4 : corriger la configuration

Trois modifications ciblées résolvent les trois erreurs.

Lire l’URL à l’aide de l’outil env de Prisma

Remplacez le contenu de prisma.config.ts par ce qui suit. Ce fichier est en TypeScript, même si l’exemple indique le contraire.

import "dotenv/config";
import type { PrismaConfig } from "prisma";
import { env } from "prisma/config";

export default {
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
    seed: "tsx prisma/seed.ts",
  },
  datasource: {
    url: env("DATABASE_URL"),
  },
} satisfies PrismaConfig;

Points à noter :

  • import "dotenv/config" charge .env avant que quoi que ce soit ne le lise. Prisma 7 ne le charge plus automatiquement dans cette configuration.
  • env("DATABASE_URL") provenant de prisma/config renvoie une string et génère une erreur explicite si la variable est absente, ce qui élimine l’erreur string | undefined.
  • satisfies PrismaConfig effectue une vérification de type sur l’objet sans l’élargir.
  • La configuration indique également où se trouvent le schéma et les migrations, ainsi que quel commandement initialise la base de données.

Restreignez ce que le compilateur inclut

Ajoutez une entrée include à la fin de tsconfig.json :

"include": ["src"],

Cela indique au compilateur de ne compiler que les fichiers situés sous src. La CLI Prisma lit toujours prisma.config.ts séparément, mais tsc cesse de le considérer comme faisant partie de votre programme, ce qui fait disparaître l’erreur rootDir et empêche toute sortie de JavaScript non désirée en dehors de dist.

Générer le client dans node_modules

Finalement, modifiez schema.prisma afin que le générateur n’ait pas de chemin de sortie personnalisé :

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"

En l’absence d’une sortie définie, le générateur prisma-client-js enregistre le client dans node_modules, de sorte qu’aucun fichier généré n’apparaît dans la racine du projet et que l’erreur liée à rootDir disparaît. Le fragment se termine après le provider de la source de données ; fermez le bloc avec une accolade. Dans Prisma 7, l’URL de connexion se trouve dans prisma.config.ts, et non dans le schéma.

Soyez conscient que c’est un compromis. Le nouveau générateur prisma-client de Prisma est conçu autour d’un répertoire de sortie explicite, tandis que prisma-client-js est le générateur plus ancien. Si vous adoptez la version récente, placez sa sortie en dehors de src et excluez-la de tsc via l’option include, comme indiqué ci-dessus.

Étape 5 : ajouter l’URL de la base de données et effectuer une migration

Placez votre chaîne de connexion dans .env. La valeur ci-dessous est un placeholder ; utilisez votre propre base de données et n’ajoutez jamais de valeurs réelles :

DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"

Définissez vos modèles dans schema.prisma, puis créez et appliquez la première migration :

npx prisma migrate dev --name init

Étape 6 : générer le client

Générez le client typé à partir du schéma :

npx prisma generate

Réexécutez cette étape chaque fois que le schéma change, afin que les types restent en synchronisation avec vos modèles.

Étape 7 : créer une instance Prisma partagée

Créez src/lib/prisma.ts pour conserver un seul client pour toute l’application. Ce fichier crée un adaptateur PostgreSQL à partir de la chaîne de connexion et le transmet à PrismaClient. Ce code est également écrit en TypeScript :

import "dotenv/config";
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../../node_modules/@prisma/client/index.js";

const connectionString = `${process.env.DATABASE_URL}`;

const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });

export default prisma;

Le client est importé via un chemin relatif explicite depuis node_modules :

import { PrismaClient } from "../../node_modules/@prisma/client/index.js";

Ce chemin fonctionne parce que le client a été généré dans node_modules à l’Étape 4. Dans la plupart des configurations, le spécificateur simple @prisma/client renvoie au même paquet, alors essayez-le en premier ; n’utilisez le chemin explicite que si vos paramètres de résolution des modules l’exigent.

Un piège dans ce fragment : envelopper process.env.DATABASE_URL dans une chaîne de template transforme une valeur manquante en le texte littéral "undefined", ce qui provoque plus tard une erreur de connexion déroutante. Une petite vérification qui lance une exception en l’absence de la variable rend les échecs évidents.

Importez maintenant cette instance là où vous avez besoin d’accéder à la base de données, comme dans les contrôleurs ou les services, et exécutez vos requêtes CRUD à travers elle. En conservant un client partagé, on évite d’ouvrir un nouveau pool de connexions pour chaque fichier.

Points clés

  • La plupart des erreurs de configuration de Prisma 7 en TypeScript proviennent des règles rootDir du compilateur, et non de Prisma lui-même.
  • Utilisez env() de prisma/config ainsi que dotenv/config pour obtenir une URL de base de données correctement typée et chargée explicitement.
  • Restreignez tsc avec "include": ["src"] afin que les fichiers d’outil et le code généré ne fassent pas partie de la compilation.
  • Gardez les clients générés en dehors de src, soit dans node_modules, soit dans un dossier de sortie exclu.
  • Créez un seul PrismaClient partagé avec l’adaptateur PrismaPg et validez la chaîne de connexion au démarrage.

Si vous utilisez Next.js plutôt qu’un service Node.js classique, notre guide sur l’installation de Prisma 7 dans un projet Next.js 16 TypeScript couvre les détails spécifiques à ce framework.