<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Модули в Nest JS - 1.2]]></title><description><![CDATA[<p dir="auto">Модуль — это важная часть приложения на Nest. Каждое приложение начинается с корневого модуля, который Nest использует для создания структуры приложения. Эта структура помогает управлять зависимостями между модулями и провайдерами.</p>
<p dir="auto">На практике это проще, чем кажется. Модули позволяют разработчикам разбивать приложение на отдельные части. Представьте, что каждый модуль — это компонент вашего приложения. Например, один модуль может отвечать за управление заказами в интернет-магазине, а другой — за управление пользователями. Вместе эти компоненты создают функциональное приложение.</p>
<p dir="auto">Важно помнить, что модули в Nest не обязательно должны быть отдельными файлами. Это всего лишь абстракция, которая помогает структурировать приложение. Некоторые модули могут быть большими, другие — маленькими. Используя паттерн «композиция», разработчики могут создавать сложные модули из простых.</p>
<p dir="auto">Хотя Nest позволяет создать приложение с одним модулем, это подходит только для очень простых проектов. С увеличением сложности приложения становится очевидным, что использование нескольких модулей — более эффективный подход.</p>
<p dir="auto"><img src="/assets/uploads/files/1731148554502-modules.jpg" alt="modules.jpg" class=" img-fluid img-markdown" /></p>
<p dir="auto"><strong>Примечание</strong>: Абстракция «Модуль» в Nest реализует одноимённый структурный паттерн проектирования. Модуль объединяет данные, функции и физические компоненты в одну сущность, а взаимодействовать с ней можно через публичный интерфейс.</p>
<h2>Как работать с модулями в Nest</h2>
<p dir="auto">В Nest модуль — это класс, помеченный декоратором @Module. Этот декоратор содержит метаданные, которые Nest использует для организации приложения.</p>
<p dir="auto">Декоратор @Module принимает объект, который описывает структуру модуля. В этом объекте можно указать провайдеры и контроллеры модуля, а также модули, от которых он зависит, и провайдеры, которые он экспортирует. Вот основные свойства:</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Свойство объекта</th>
<th>Описание</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>providers</code></td>
<td>Список провайдеров модуля.</td>
</tr>
<tr>
<td><code>controllers</code></td>
<td>Список контроллеров модуля.</td>
</tr>
<tr>
<td><code>imports</code></td>
<td>Список импортируемых модулей.</td>
</tr>
<tr>
<td><code>exports</code></td>
<td>Список экспортируемых провайдеров модуля.</td>
</tr>
</tbody>
</table>
<p dir="auto">Особое внимание стоит уделить свойствам imports и exports.</p>
<ul>
<li>
<p dir="auto"><code>imports</code>: здесь указываются модули, которые нужны текущему модулю. Если модуль использует функциональность других модулей, их нужно перечислить в этом свойстве. Импортированные модули могут использовать экспортируемые провайдеры.</p>
</li>
<li>
<p dir="auto"><code>exports</code>: в этом свойстве перечисляются провайдеры, которые будут доступны другим модулям при импорте. Это позволяет делиться функциональностью между модулями.</p>
</li>
</ul>
<p dir="auto">По умолчанию все провайдеры модуля скрыты. Чтобы использовать провайдер в другом модуле, его нужно экспортировать через свойство <code>exports</code>. Таким образом, экспортируемые провайдеры можно считать публичным интерфейсом модуля.</p>
<h2>Модули на практике</h2>
<p dir="auto">Чтобы понять, как работают модули в Nest, рассмотрим пример простого приложения — API для управления пользователями. В этом приложении нам понадобятся функции для запуска сервера и управления пользователями.</p>
<p dir="auto">Для REST API создадим контроллер <code>UserController</code>, который будет обрабатывать маршруты. Если у нас есть бизнес-логика и взаимодействие с базой данных, нам понадобится модуль <code>UserService</code>, который будет реализовывать эту логику. Также потребуется описание сущности «Пользователь», например, <code>UserEntity</code>.</p>
<p dir="auto">Каждый из этих элементов будет храниться в отдельном файле, что делает структуру проекта более удобной и понятной. Примерная схема файловой структуры может выглядеть следующим образом:</p>
<p dir="auto"><img src="/assets/uploads/files/1731148868985-modules-1.jpg" alt="modules-1.jpg" class=" img-fluid img-markdown" /></p>
<p dir="auto">Давайте рассмотрим, что общего у контроллера, сервиса и сущности — все они относятся к одной области, связанной с управлением пользователями. Такие области называются доменами.</p>
<p dir="auto"><strong>Примечание</strong>: <strong>Домен</strong> — это предметная область, которая включает бизнес-логику, процессы, данные и терминологию, связанные с этой областью.</p>
<p dir="auto">Поскольку все эти элементы связаны, имеет смысл объединить их в функциональный модуль. Модуль «Пользователи» будет отвечать за работу с пользователями и предоставит публичный интерфейс для взаимодействия с другими модулями. Разработчик сможет использовать функциональность модуля, не углубляясь в детали его реализации.</p>
<p dir="auto">С ростом приложения появятся и другие модули, например, для управления заказами или отправкой уведомлений. Разделение на функциональные модули упростит поддержку и установит четкие границы для каждого из них.</p>
<p dir="auto"><strong>Примечание</strong>: <strong>Nest CLI</strong> позволяет быстро создать модуль с помощью команды: <code>nest g module users</code>.</p>
<p dir="auto">Пример организации кода для нашего модуля может выглядеть так:</p>
<pre><code class="language-ts">import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';

@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {}
</code></pre>
<p dir="auto">Новый модуль описывается как класс, например, <code>UserModule</code>, и помечается декоратором <code>@Module</code>. В этот декоратор передаётся объект с настройками модуля, где мы регистрируем контроллеры и провайдеры.</p>
<p dir="auto">Наш модуль пока ничего не экспортирует, но при необходимости можно добавить сервисы для использования в других модулях. Для этого в объект настроек нужно добавить свойство <code>exports</code>. Мы рассмотрим это на практике позже.</p>
<p dir="auto"><strong>Примечание</strong>: Хороший модуль должен решать одну конкретную задачу. Не стоит объединять всю функциональность приложения в одном модуле. Лучше разбивать на несколько, минимизируя зависимости между модулями.</p>
<p dir="auto"><img src="/assets/uploads/files/1731149143482-modules-2.jpg" alt="modules-2.jpg" class=" img-fluid img-markdown" /></p>
<p dir="auto">Для каждого модуля обычно создаётся отдельная директория, где размещаются все его компоненты: сервисы, контроллеры и вспомогательные скрипты. Это позволяет удобно организовать код и иметь всё, что связано с модулем, в одном месте.</p>
<h2>Подключение модуля</h2>
<p dir="auto">Чтобы использовать функциональность модуля, его нужно подключить в другом модуле. Как уже упоминалось, любое приложение на Nest состоит как минимум из одного модуля, который называется корневым (обычно <code>AppModule</code>). Чтобы активировать функциональность <code>UserModule</code>, его необходимо подключить к корневому модулю приложения.</p>
<pre><code class="language-ts">// Файл app.module.ts

import { Module } from '@nestjs/common';
import { UserModule } from './cats/user.module';

@Module({
  imports: [UserModule],
})
export class AppModule {}
</code></pre>
<p dir="auto">После подключения модуля <code>UserModule</code>, его функциональность становится активной. Обработчики маршрутов в контроллере <code>UserController</code> будут срабатывать при совпадении маршрута.</p>
<h2>Переиспользование модулей</h2>
<p dir="auto">Создание и подключение модулей в Nest довольно просто. Разработчику нужно лишь следовать публичным интерфейсам. Nest автоматически управляет экземплярами классов модулей, и вам не нужно создавать их вручную.</p>
<p dir="auto">Все модули в Nest по умолчанию являются синглтонами. Это значит, что один и тот же экземпляр провайдера можно использовать в разных модулях. Таким образом, каждый модуль может быть повторно использован другими модулями.</p>
<p dir="auto">Например, если нужно разделить экземпляр <code>UserService</code> между модулями, просто экспортируйте этот провайдер из <code>UserModule</code>. Для этого добавьте соответствующий ключ в объект настроек модуля:</p>
<pre><code class="language-ts">import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';

@Module({
  controllers: [UserController],
  providers: [UserService],
  
  // Добавляем экспорт провайдера
  exports: [UserService]
})
export class UserModule {}
</code></pre>
<p dir="auto">Теперь любой модуль, который импортирует <code>UserModule</code>, получает доступ к <code>UserService</code>, используя один и тот же экземпляр.</p>
<h2>Реэкспорт модулей</h2>
<p dir="auto">Модули могут экспортировать не только свои провайдеры, но и другие модули, которые они импортируют. Это называется реэкспортом модулей и значительно расширяет возможности для композиции. В коде реэкспорт модулей работает так же, как экспорт провайдеров. Рассмотрим это на примере.</p>
<pre><code class="language-ts">@Module({
  imports: [FooModule],
  exports: [FooModule]
})
export class UserModule {}
</code></pre>
<p dir="auto">Принцип остаётся прежним: в <code>exports</code> можно перечислять как провайдеры, так и модули для реэкспорта. В приведённом примере <code>UserModule</code> импортирует <code>FooModule</code> и реэкспортирует его, делая доступным для других модулей, которые импортируют <code>UserModule</code>.</p>
<h2>Внедрение зависимостей</h2>
<p dir="auto">В класс модуля можно внедрять провайдеров как зависимости через конструктор. Это может быть полезно при настройке модуля. Рассмотрим это на примере:</p>
<pre><code class="language-ts">import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';

@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {
  // UserService внедряется с помощью DI
  constructor(private userService: UserService) {}
}
</code></pre>
<p dir="auto">Важно помнить, что классы модулей не могут быть провайдерами из-за возможных циклических зависимостей.</p>
<h2>Глобальные модули</h2>
<p dir="auto">В приложении часто появляются модули, которые нужно импортировать в разных местах, например, хелперы или модули для работы с базой данных. Чтобы не повторять процедуру импорта, Nest позволяет создавать глобальные модули. Все провайдеры таких модулей будут доступны во всем приложении.</p>
<p dir="auto">Чтобы сделать модуль глобальным, нужно аннотировать его декоратором <code>@Global</code>. Глобальные модули регистрируются только один раз, обычно в корневом модуле приложения.</p>
<p dir="auto">Рассмотрим пример с модулем <code>UserModule</code>. Аннотируем его декоратором <code>@Global</code>, и теперь провайдер <code>UserService</code> станет доступен другим модулям для внедрения без необходимости импортировать <code>UserModule</code>.</p>
<pre><code class="language-ts">import { Module, Global } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';

// Сделаем модуль глобальным
@Global()
@Module({
  controllers: [UserController],
  providers: [UserService],

  // Экспортируемые провайдеры
  // доступны другим модулям для внедрения
  // в качестве зависимости без необходимости
  // импортировать UserModule.
  exports: [UserService],
})
export class UserModule {}
</code></pre>
<p dir="auto">Хотя создание глобальных модулей удобно, использовать эту возможность нужно осторожно. Не стоит делать все модули глобальными, так как это может привести к сильной связанности между ними. Когда приложение вырастет, будет трудно отслеживать связи между модулями, и рефакторинг станет сложным. Используйте глобальные модули с осторожностью.</p>
<h2>Заключение</h2>
<p dir="auto">Модуль — это ключевая абстракция в Nest. Его можно сравнить с компонентом, отвечающим за определённую функциональность приложения. Мы рассмотрели, как объявлять модули, использовать декоратор @Module, выполнять реэкспорт модулей и другие аспекты.</p>
<p dir="auto">Любое Nest-приложение состоит минимум из одного модуля, но не стоит складывать всю функциональность в один модуль. Разделение на модули упрощает поддержку и выделяет функциональность в отдельные компоненты.</p>
]]></description><link>https://forum.exlends.com/topic/36/moduli-v-nest-js-1-2</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 01:11:00 GMT</lastBuildDate><atom:link href="https://forum.exlends.com/topic/36.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 09 Nov 2024 10:58:16 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Модули в Nest JS - 1.2 on Mon, 27 Jan 2025 13:21:01 GMT]]></title><description><![CDATA[<p dir="auto">Круто! Давай про Гварды еще</p>
]]></description><link>https://forum.exlends.com/post/127</link><guid isPermaLink="true">https://forum.exlends.com/post/127</guid><dc:creator><![CDATA[Mugiwara]]></dc:creator><pubDate>Mon, 27 Jan 2025 13:21:01 GMT</pubDate></item></channel></rss>