Головна / Статті

Налаштування Prisma 7 з PostgreSQL у проекті TypeScript Node.js

Виправте поширені помилки налаштування Prisma 7 у TypeScript — від проблем із рядками чи невизначеними URL до скарг щодо rootDir — та під’єднайте PostgreSQL за допомогою адаптера драйвера pg.

Видавець: REACTAPP.TOP7 хв читання1666 слів

Джерела: I Wasted 4 Hours Setting Up Prisma — Here’s How You Should Set Up Prisma v7

Виконання посібника з швидкого старту Prisma у звичайному проекті TypeScript для Node.js часто закінчується безліччю помилок компілятора ще до того, як виконається хоча б один запит. Проблеми не в моделях; вони виникають через те, як компілятор TypeScript, новий файл конфігурації Prisma та створений клієнт взаємодіють із традиційною структурою src/dist. У цьому посібнику пояснюються три найпоширеніші помилки, чому вони виникають, а також поетапна налаштування з PostgreSQL, яка дозволяє без проблем компілювати код. Prisma 7 змінила кілька значень за замовчуванням, тому перевірте актуальну документацію Prisma на наявність змін з моменту написання цього посібника.

Три помилки, які заважають правильній налаштуванню

Адреса підключення введена як рядок або є невизначеною

У файлі prisma.config.ts URL бази даних зазвичай отримується за допомогою process.env.DATABASE_URL. TypeScript класифікує кожну змінну середовища як string | undefined, оскільки немає гарантій її налаштування під час виконання. Конфігурація очікує звичайний тип string, тому компілятор відхиляє це присвоєння.

prisma.config.ts поза кореневим каталогом

Типовий проект TypeScript встановлює rootDir як src, а outDir — як dist. Prisma створює файл prisma.config.ts у корені проекту, і за замовчуванням компілятор включає кожен знайдений файл .ts. Потім він повідомляє про помилку, що файл, розташований поза rootDir, є частиною програми. Переміщення конфігурації до src припинить цю помилку, але це неправильне рішення: src призначений для коду додатку, такого як маршрути, контролери та засоби доступу до даних, а не для конфігурації інструментів.

Генерований клієнт поза кореневим каталогом

Те саме відбувається з генерованим клієнтом. Якщо Prisma зберігає його у директорії generated/prisma у корені проекту, компілятор знову знаходить файли TypeScript поза межами rootDir. Розміщення генерованого коду у src також є поганою ідеєю, оскільки це результат компіляції з команди prisma generate, а не вихідний код, який потрібно підтримувати.

Якщо ці проблеми залишити нерозв’язаними, вони заважатимуть запуску проекту. Ще один дратівливий наслідок — скомпільований JavaScript для prisma.config.ts може опинитися поза директорією dist, що забруднює репозиторій. Виправлення помилок по одній зазвичай призводить до виникнення нових, тому варто виправити налаштування в цілому.

Крок 1: створити проект та встановити залежності

Почніть з порожнього проекту TypeScript. Встановіть компілятор, tsx для безпосередньої роботи з TypeScript та типові визначення Node, а потім створіть файл tsconfig.json:

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

Далі встановіть Prisma. CLI та типові визначення pg є залежностями для розробки; клієнт, адаптер драйвера PostgreSQL, драйвер pg та dotenv є залежностями під час виконання:

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

Тут важлива пакетна бібліотека @prisma/adapter-pg. У Prisma 7 клієнт взаємодіє з базою даних через адаптер драйвера JavaScript, тому ви передаєте йому налаштоване з’єднання pg, а не просто URL, вказаний у схемі.

Крок 2: налаштування ES-модулів та структури компілятора

Відмітіть пакет як ES-модуль у файлі package.json:

{
  "type": "module"
}

Потім встановіть каталоги вихідних даних та результату у файлі tsconfig.json, а також створіть папку src:

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

Крок 3: ініціалізація Prisma

Запустіть CLI один раз (це просто виведе доступні команди та підтвердить, що встановлення працює):

npx prisma

Потім ініціалізуйте Prisma для PostgreSQL:

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

Це створює файл prisma.config.ts, папку prisma, яка містить файл schema.prisma, та файл .env для URL бази даних. Параметр --output визначає місце створення клієнта; цей вибір розглядається на Кроці 4. Саме після цього кроку з’являються описані вище помилки.

Крок 4: виправлення конфігурації

Три цілеспрямовані зміни усувають усі три помилки.

Читання URL за допомогою функції env від Prisma

Замініть вміст prisma.config.ts на наведений нижче. Цей файл написаний на TypeScript, хоча у фрагменті це інакше позначено.

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;

Що варто зазначити:

  • import "dotenv/config" завантажує файл .env ще до того, як хтось його прочитає. У Prisma 7 цей файл більше не завантажується автоматично в такій конфігурації.
  • env("DATABASE_URL") з модуля prisma/config повертає значення типу string, і у разі відсутності змінної виникає чіткий помилковий повідомлення, що усуває можливість помилки типу string | undefined.
  • satisfies PrismaConfig перевіряє об’єкт на відповідність типу, не розширюючи його.
  • У конфігурації також вказується, де знаходяться схеми та міграції, а також яка команда заповнює базу даних.

Обмежте те, що включає компілятор

Додайте запис include у кінець файлу tsconfig.json:

"include": ["src"],

Це наказує компілятору обробляти лише файли, розташовані в папці src. Prisma CLI все ще читає файл prisma.config.ts окремо, але tsc перестає розглядати його як частину вашої програми, тому помилка rootDir зникає, і жоден зайвий JavaScript не виводиться за межі папки dist.

Створення клієнта у node_modules

Наостанок відредагуйте файл schema.prisma, щоб генератор не мав власного шляху виведення:

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

datasource db {
  provider = "postgresql"

Без параметра output генератор prisma-client-js зберігає клієнт у директорії node_modules, тому нічого не залишається у корені проекту, і помилка щодо rootDir зникає. Фрагмент коду закінчується після определення provider для джерела даних; закрийте блок круглими дужками. У Prisma 7 URL для підключення знаходиться у файлі prisma.config.ts, а не в схемі.

Пам’ятайте, що це компроміс. Новіший генератор Prisma prisma-client розроблений з урахуванням чітко визначеної директорії виведення, тоді як prisma-client-js є старішим генератором. Якщо ви обираєте новіший варіант, зберігайте результат його роботи поза директорією src та виключіть його з обробки tsc за допомогою параметра include, як описано вище.

Крок 5: додайте URL бази даних та виконайте міграцію

Розмістіть свій рядок підключення у файлі .env. Значення нижче є замінником; використовуйте власну базу даних та ніколи не зберігайте справжні значення:

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

Визначте свої моделі у файлі schema.prisma, а потім створіть та застосуйте першу міграцію:

npx prisma migrate dev --name init

Крок 6: створення клієнта

Створіть типованого клієнта на основі схеми:

npx prisma generate

Запускайте цей процес знову щоразу, коли змінюється схема, щоб типи залишалися синхронізованими з вашими моделями.

Крок 7: створення спільної інстанції Prisma

Створіть файл src/lib/prisma.ts, який буде містити одного клієнта для всього додатку. У цьому файлі створюється адаптер до PostgreSQL на основі рядка підключення, який потім передається до об’єкта PrismaClient. Цей код також написаний на 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;

Клієнт імпортується через явний відносний шлях у директорію node_modules:

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

Цей шлях працює тому, що клієнт був створений у директорії node_modules на кроці 4. У більшості конфігурацій прямий специфікатор @prisma/client вказує на той самий пакет, тож спробуйте його спочатку; звертайтеся до прямого шляху лише тоді, коли це вимагають налаштування розрішення модулів.

Одна з проблем у цьому фрагменту: обгортання значення process.env.DATABASE_URL у рядок-шаблон перетворює відсутнє значення на текст "undefined", що згодом призводить до заплутаних помилок підключення. Коротка перевірка, яка кидає помилку при відсутності змінної, робить проблеми очевидними.

Тепер імпортуйте цей клієнт там, де вам потрібен доступ до бази даних — наприклад, у контролерах чи сервісах, і виконуйте свої запити CRUD через нього. Використання одного спільного клієнта дозволяє уникнути створення нового пулу з’єднань для кожного файлу.

Основні висновки

  • Більшість помилок налаштування Prisma 7 у TypeScript виникають через правила rootDir компілятора, а не через сам Prisma.
  • Використовуйте env() з модуля prisma/config разом із dotenv/config, щоб отримати URL бази даних із правильним типуванням та явним завантаженням.
  • Обмежте дію tsc за допомогою параметра "include": ["src"], щоб файли інструментів та генерований код не потрапляли до результату компіляції.
  • Зберігайте генеровані клієнти поза директорією src — у каталозі node_modules або у окремій директорії для виключених файлів.
  • Створіть один спільний об’єкт PrismaClient із адаптером PrismaPg та перевіряйте рядок підключення під час запуску.

Якщо ви використовуєте Next.js замість звичайного сервісу Node.js, наш посібник з встановлення Prisma 7 у проекті Next.js 16 на TypeScript охоплює деталі, специфічні для цього фреймворку.