Язык Javascript сам по себе прекрасен, про Typescript мы тут говорить не будем. Но что же не так с NodeJS? (по мнению автора)

Будем не столько о технологии в целом, сколько о применении её для веб-проектов. А веб-проект почти в любом случае, будет не более, чем типичным, ничего нового мы по факту не создаем.

Платформа развивается, оптимизируется, появляются правильные вещи, многое встраивается в стандартную библиотеку, может быть и лодаш скоро станет не нужен. Много работы кипит в кишках ноды, умные люди оптимизируют и ускоряют.

Все куда-то движется, NodeJS идёт 15-й год (Node.js was initially written by Ryan Dahl in 2009), библиотеки и драйвера есть для всего на свете, люди умеют писать проекты разной степени сложности, программисты создают типичные веб-приложения уже по 10 или 15 разу. Есть все условия. А единого подхода как сделать типичный вебчик - нет. Его не было на заре появления ноды, его нет и сейчас.

Мы меняем работу, меняем проект, приходим, открываем проект с которым нам предстоит работать - что мы видим? Созданный почти с нуля набор библиотек, переплетенных вместе, свой роутер, огромный набор миддлвар на все случаи жизни, руками написанная интеграция работы с базой данных, очень часто - отсутствие тестов в проекте, либо попытка написать парочку юнитов, но без более комплексного подхода к тестированию приложения как единого целого.

  • Нам нужны консьюмеры, чтобы читать из очереди - напишем че-то свое. Но ведь есть библиотека! (amqplib)
  • Нам нужно сделать периодические задачи - напишем свое, как тестировать - подумаем позже, может и вообще не думать. Но ведь есть библиотека! (node-cron)
  • Нам нужно сделать рендеринг HTML на сервере? Не SSR а типа по-старому - соберем что-то из говна и палок, каждый напишет свои тулзы и миксины для pug и пошло-поехало. Но ведь есть библиотека! (pug)
  • Нам нужны отложенные задачи? Сделай и прикрути сам. Но ведь есть библиотека! (bull)
  • Как организовать структуру проекта, пока он еще не стал большим? (А 99% проектов и не становятся большими). Но ведь есть NestJS.

Изначально я хотел взять пример более менее типичного проекта, ну например тот же блог, в котором есть апи и админская часть апи, крон-задачи, например, для синхронизации каких-либо ассетов, простой рендеринг HTML на сервере, и тесты из коробки. Хотел взять и написать его на 4 фреймворках (rails, laravel, phoenix, nestjs), но я осознал, что мне не хватит сил на это, поэтому эксперимент будет просто мысленным. Сразу оговорюсь, кроме неста я ничего брать не стал, потому что все остальное пребывает в еще более зародышевом состоянии.

Итак, пройдемся по пунктам, к которым у меня есть претензии.

  1. Генерация проекта, в котором всё включено (тесты/вьюхи/модели/контроллеры) - умеют все, кроме неста (нест пытается, но получается hello world), зато примеров микропроектов - дофига. Какой-нибудь ларавель тебе может дать скаффолд авторизации из коробки, рейлс думаю тоже
  2. CLI для удобного взаимодействия с проектом, просмотра роутов, наката бд миграций, работы с ассетами, работы с мейлами
  3. Тесты - нест дает парочку примеров для юнит тестов и для e2e - но абсолютно нет никакого понимания - КАК писать тесты, как интегрироваться с БД, что с фабриками, сидами и фикстурами, как чистить БД, что с автооткатами транзакций и всем остальным, как писать тест хелперы, и расширять тест сьюты? Собственно из-за абсолютного игнорирования интеграции фреймворка с подходами к тестированию - приложение вообще не разделяется на отдельный бутстрап и точку входа
  4. Модели - нест не сгенерит тебе проект, в котором ОРМ сразу подрублена и сразу работает - мучайся сам, ну хотя бы есть документация. Из-за пункта выше - нет интеграции тестов в плане подготовки тестовых данных с модельным рядом опять же
  5. Вьюхи - их тоже не будет, щас так не модно, у нас везде JSON API. Но есть документация - собери сам, если во вьюхах нужна будет локализация - мучайся, вьюхи не связаны с контроллерами, соответственно не будет никаких удобных роутинг хелперов и всего остального. Это просто еще одна часть пазла, который ты должен собрать сам
  6. Структура проекта - вопрос шкурный, нест пропагандирует что он даёт нам архитектуру. Только она отстойная. Как мне написать просто бложек? Где будут модельки, где контроллеры, где вьюхи? Мне самому придумать? Или разложить каждую энтити в отдельную папку, а потом притворяться, что это все разные контексты?
  7. Логирование - первый фреймворк, где пришлось думать о том какой-же мне логгер взять - хотя тут вопрос больше к экосистеме ноды - бери любой, не забудь померить бенчмарком, что у меня самый большой перформанс при логировании. Эх, а ведь так часто не хватает PSR-3 из PHP - хотя такого стандарта нет нигде, кроме PHP
  8. Роутинг - я думаю что самые прекрасные роутинги в рельсах и фениксе - они декларативны, декоратор бейзед симфони/спринг стайл - это тот самый роутинг, который при росте проекта - надо наизусть знать как все устроено, ты не сможешь ничего там найти, потому что оно будет разбросано по файлам/классам/функциям/декораторам. Как организовать разделение на админскую часть и публичный апи - например Phoenix - дает тебе разделение роутов по пайплайнам, и соответственно навешивание групп миддлвар на каждый пайплайн
  9. Email - собери сам, интегрируй с тестами сам
  10. Graceful shutdown - настрой и сделай сам, оно не заведется с первого раза, нужно лезть в кишки будет

Мне надоел набор библиотек, я хочу фреймворк, в котором это все встроено и задокументировано. Задачи, которые я описал выше, наверное, за исключением шаблонизации на сервере - типичные для всех веб-проектов и есть всегда. Так доколе каждый будет собирать свое чудовище? NestJS - это все еще микрофреймворк и на звание полноценного инструмента не тянет.

В общем и целом, всегда возникает ощущение, что все нужно докручивать напильником. Из-за этого, каждый проект становится уникальным и нетипичным, программист из 2022 открывает проект на несте в 2025 и должен будет заново понимать, что тут происходит. Программист из 2010 откроет в 2020 проект на rails и через пару часов начнет свою работу. Ладно еще нест, он привнес хоть какой-то порядок, но представьте, что каждый собрал своего монстра из koa/express/fastify, 20+ express middlwares, jest/mocha, node-cron, knex/objectionjs/typeorm/sequalize/mikroorm, axios, amqplib, commander, ioredis, nodemailer, socket.io, winston, yaml, zod, joi ну и так далее, список будет бесконечным, и в каждом проекте разным.

Обещал не говорить тут про тайпскрипт - но давай приправим еще все этим комбайном, и у нас три способа запуска проекта - для прода, для локальной разработки с лайврелоадом и для тестов - с быстрой транспиляцией без тайпчекинга.

Остается вопрос - почему так сложно?