Ответ
В моем опыте работы с Nest.js были следующие сложности:
-
Сложность внедрения зависимостей (DI) на старте. При неправильной настройке модулей контейнер не может разрешить зависимости. Я сталкивался с ошибками вида:
// Nest can't resolve dependencies of the ServiceA (?). // Please make sure that the argument ServiceB at index [0] is available in the AppModule context.Решение — тщательно следить за тем, чтобы провайдеры были зарегистрированы в нужном модуле и область видимости (scope) была понятна.
-
Интеграция с ORM. При использовании TypeORM в сочетании с миграциями иногда возникали конфликты, особенно при работе в команде, когда состояние базы данных у разработчиков расходилось.
-
Тестирование. Мокирование сложных зависимостей, особенно кастомных провайдеров или сервисов, использующих декораторы (например,
@InjectRepository()), требовало большего количества boilerplate-кода по сравнению с простым Express-приложением. -
Производительность. Из-за множества слоев абстракции (декораторы, интерсепторы, пайпы) некоторые эндпоинты, особенно с тяжелой бизнес-логикой, могли показывать более высокую latency. Это требовало дополнительного профилирования и оптимизации.
Ответ 18+ 🔞
А, Nest.js, говоришь? Ну, это как купить немецкий автомобиль — вроде всё продумано, едет ровно, но если какая-то хрень сломается, то разбираться будешь до потери пульса, и запчасти — отдельная песня.
Первый пункт твой — про DI — это вообще классика, ёпта. Ты только начинаешь проект, такой весь из себя архитектор, настраиваешь модули, а тут тебе — хуй с горы — ошибка, что какой-то ServiceB не найден. И сидишь, смотришь в код, а там всё вроде импортировано, провайдер объявлен. А оказывается, что ты этот сервис в exports модуля забыл добавить, или область видимости REQUEST поставил, а он тебе в другом месте нужен. Пока разберёшься, уже терпения ноль, ебать. Это как собирать шкаф из Икеи, когда одной детали не хватает, и ты понимаешь, что она, скорее всего, в другой коробке, которую ты уже выбросил.
Про ORM и миграции — это отдельный цирк. TypeORM, конечно, мощная штука, но когда в команде пять человек, и у каждого своя ветка, и миграции плодятся как кролики, то состояние базы начинает напоминать сюрреалистичный сон. Один запушил миграцию, другой её не потянул, сделал свою от другой точки — и понеслась. Волнение, ебать, когда пытаешься всё это смержить и не сломать прод. Иногда кажется, что проще было бы руками SQL писать, честное слово.
А тестирование... О, это моя любимая головная боль. В простом Express-приложении ты взял, замокал req и res, и всё, поехали. А тут у тебя Nest со своим DI-контейнером. Хочешь замокать репозиторий, который инжектится через @InjectRepository()? Приготовься писать овердохуища boilerplate-кода. Создавай кастомный провайдер, настраивай TestingModule — к моменту, когда ты наконец напишешь тест, желание тестировать что-либо улетучивается вместе с последними силами. Доверия, ебать, ноль к тому, что после рефакторинга все твои моки ещё будут работать.
Ну и латентность, да. Абстракции — это, конечно, хорошо для поддержки и архитектуры. Но иногда чувствуешь, что каждый твой запрос проходит через ёперный театр из декораторов, гуардов, интерсепторов и пайпов, прежде чем дойти до контроллера. И если бизнес-логика ещё и тяжёлая, то всё, пиши пропало. Начинаешь профилировать, а оказывается, что пол-секунды уходит не на запрос к базе, а на то, чтобы фреймворк «разогрелся» и прошёл все свои слои. Приходится выкручиваться, что-то выносить, оптимизировать — в общем, ядрана вошь, а не работа.
В общем, инструмент мощный, но иногда создаётся впечатление, что ты не столько бизнес-задачу решаешь, сколько с самим фреймворком борешься. Как будто купил невероятно навороченную кофеварку, чтобы просто с утра эспрессо выпить, а половину времени тратишь на её чистку и настройку помола.