Пошук уроків, статей та іншого контенту
Як NestJS групує пов'язані контролери й провайдери в самодостатні модулі, що складаються в дерево.
Модуль у NestJS — клас, позначений декоратором @Module, що групує пов'язані контролери й провайдери в одну логічну одиницю — типово одну на кожну предметну область застосунку (користувачі, замовлення, автентифікація). Кожен NestJS-застосунок має щонайменше один кореневий модуль (за конвенцією AppModule), з якого NestJS будує все дерево залежностей під час старту.
import { Module } from "@nestjs/common";
import { CatsController } from "./cats.controller";
import { CatsService } from "./cats.service";
@Module({
controllers: [CatsController], // обробники HTTP-запитів цього модуля
providers: [CatsService], // сервіси/бізнес-логіка цього модуля
})
export class CatsModule {}controllers — контролери, що належать цьому модулю (детально в наступному уроці).
providers — сервіси та інші класи, доступні для впровадження залежностей у межах модуля (детально в модулі про Dependency Injection).
imports — список інших модулів, чиї експортовані провайдери потрібні цьому модулю.
exports — підмножина власних providers, які цей модуль дозволяє використовувати іншим модулям, що його імпортують.
import { Module } from "@nestjs/common";
import { CatsModule } from "./cats/cats.module";
import { UsersModule } from "./users/users.module";
@Module({
imports: [CatsModule, UsersModule], // кореневий модуль лише збирає фічеві модулі докупи
})
export class AppModule {}Типова структура великого NestJS-застосунку — по одному модулю на предметну область (feature module), кожен зі своїми контролерами й сервісами, а кореневий AppModule лише імпортує їх усі — та сама ідея композиції, що й у побудові UI з менших React-компонентів (курс React), тільки на рівні серверної архітектури.
Провайдер, оголошений у providers одного модуля, за замовчуванням недоступний в іншому модулі, навіть якщо той модуль його імпортував, — доступ відкривається лише через явний exports. Це навмисна інкапсуляція: модуль контролює, яку саме частину своєї внутрішньої логіки він готовий ділити із зовнішнім світом.
Найпоширеніша помилка новачків — забути додати провайдер в exports і дивуватись помилці «Nest can't resolve dependencies» в іншому модулі, хоча провайдер оголошений і працює в межах свого власного модуля.
Забути exports для провайдера, який мають використовувати інші модулі — провайдер лишається доступним лише всередині свого модуля.
Класти всі контролери й сервіси застосунку в один AppModule замість розбиття на фічеві модулі — втрачається і структурованість, і можливість повторно використати модуль в іншому проєкті.
Плутати imports модуля NestJS з import JavaScript-модулів (курс JavaScript, ES Modules) — це різні механізми на різних рівнях: один про залежності класів під час виконання, інший — про файлову систему й компіляцію.
Модуль (@Module) групує пов'язані контролери й провайдери, зазвичай по одному на предметну область застосунку, а кореневий AppModule збирає фічеві модулі докупи через imports. Провайдери модуля за замовчуванням інкапсульовані — доступні іншим модулям лише через явний exports, що дає контроль над тим, яка частина внутрішньої логіки модуля стає публічною.