1. Введение в экосистему: настройка окружения, TypeScript и архитектура монорепозитория
Введение в экосистему: настройка окружения, TypeScript и архитектура монорепозитория
Добро пожаловать в курс Fullstack разработка на Next.js и Nest.js. В этой первой статье мы заложим фундамент для всего будущего приложения. Мы не просто напишем «Hello World», а создадим профессиональную архитектуру, которую используют в крупных технологических компаниях.
Наша цель — создать приложение, где фронтенд (Next.js) и бэкенд (Nest.js) говорят на одном языке, буквально и фигурально. Этим языком будет TypeScript.
Почему именно этот стек?
Выбор технологий в 2024 году огромен, но связка Next.js и Nest.js выделяется своей мощью и типизацией.
Next.js: Фронтенд без компромиссов
Next.js — это фреймворк поверх React, который решает главные проблемы чистого React: SEO (оптимизация для поисковиков) и производительность первой загрузки. Он делает это с помощью SSR (Server-Side Rendering — рендеринг на стороне сервера).> Next.js предоставляет вам лучший опыт разработчика со всеми функциями, необходимыми для производства: гибридный статический и серверный рендеринг, поддержка TypeScript, интеллектуальное связывание, предварительная выборка маршрутов и многое другое. Next.js Documentation
Nest.js: Порядок на бэкенде
Если вы приходите из мира Express.js, вы знаете, что там можно писать код как угодно. Это часто приводит к хаосу. Nest.js навязывает строгую модульную архитектуру, вдохновленную Angular. Он использует декораторы, внедрение зависимостей (Dependency Injection) и отлично работает с TypeScript.!Схема взаимодействия клиента и сервера через общие типы данных в монорепозитории
Архитектура монорепозитория
Традиционно фронтенд и бэкенд хранятся в разных репозиториях. Это создает проблему синхронизации: вы обновили API на бэкенде, но забыли обновить типы на фронтенде. Приложение падает.
Мы будем использовать монорепозиторий. Это стратегия, при которой код нескольких проектов (в нашем случае client и server) хранится в одном репозитории.
Преимущества монорепозитория:
packages/shared, где опишем интерфейсы данных. И фронтенд, и бэкенд будут использовать одни и те же файлы. Если бэкенд изменит формат ответа, фронтенд сразу «подсветит» ошибку на этапе компиляции.Настройка окружения
Для начала работы нам понадобятся правильные инструменты. Мы будем использовать pnpm вместо npm или yarn. Pnpm (Performant NPM) работает быстрее и экономит место на диске за счет умного использования симлинков.
Шаг 1: Установка Node.js
Убедитесь, что у вас установлена Node.js версии LTS (Long Term Support). На момент написания курса это версия 20+.Проверьте версию в терминале:
Если Node.js не установлен, скачайте его с официального сайта Node.js.
Шаг 2: Установка pnpm
Если у вас еще нет pnpm, установите его глобально:
Создание структуры проекта
Мы создадим структуру вручную, чтобы понимать каждый винтик системы. Мы будем использовать встроенные возможности pnpm workspaces.
Создайте папку проекта и перейдите в неё:
Инициализируйте проект:
Теперь создадим файл конфигурации рабочего пространства pnpm-workspace.yaml в корне проекта. Этот файл говорит pnpm, где искать наши приложения и пакеты.
Создайте файл pnpm-workspace.yaml и добавьте туда следующий код:
Теперь создадим необходимые папки:
* apps/ — здесь будут лежать наши запускаемые приложения (Next.js и Nest.js). * packages/ — здесь будут лежать вспомогательные библиотеки (общие типы, конфиги).
Шаг 3: Установка Nest.js (Server)
Перейдем в папку apps и создадим серверное приложение. Для этого нам понадобится Nest CLI. Я рекомендую использовать npx для запуска последней версии CLI без глобальной установки.
При вопросе о пакетном менеджере выберите pnpm.
Теперь у нас есть папка apps/server с готовым бэкендом.
Шаг 4: Установка Next.js (Client)
Находясь всё ещё в папке apps, создадим клиентское приложение:
Вас спросят о настройках. Рекомендую выбирать следующие варианты для этого курса:
* TypeScript: Yes
* ESLint: Yes
* Tailwind CSS: Yes (мы будем его использовать позже)
* src/ directory: Yes
* App Router: Yes (это современный стандарт Next.js)
Customize import alias: No (или @/ по умолчанию)
Теперь у нас есть следующая структура:
Настройка TypeScript и общих типов
Самая важная часть монорепозитория — возможность переиспользовать код. Давайте создадим пакет с общими типами.
packages/shared.package.json (внутри packages/shared) на что-то уникальное для вашего проекта, например @course/shared.index.ts:Теперь нам нужно, чтобы и client, и server видели этот пакет. Благодаря pnpm workspaces, нам не нужно публиковать этот пакет в npm. Мы просто добавим его как зависимость.
Зайдите в apps/client/package.json и добавьте в dependencies:
Сделайте то же самое для apps/server/package.json.
После этого выполните команду в корне проекта:
pnpm создаст символические ссылки, и теперь вы можете импортировать IUser в обоих проектах так:
Важность tsconfig.json
TypeScript требует настройки. В корне каждого приложения (apps/client и apps/server) есть файл tsconfig.json. Убедитесь, что в обоих файлах включен строгий режим:
Strict mode (строгий режим) запрещает неявный тип any и заставляет вас писать более надежный код. Это может показаться сложным поначалу, но это спасает от тысяч багов в будущем.
Запуск проектов
Чтобы разрабатывать комфортно, нам нужно запускать оба проекта параллельно. Мы можем открывать два терминала, но это неудобно. Давайте добавим скрипт в корневой package.json.
Установим утилиту concurrently в корень (как dev-зависимость):
Добавьте скрипт в корневой package.json:
Разберем эту команду:
* concurrently — запускает команды параллельно.
* pnpm --filter server start:dev — запускает команду start:dev только внутри папки server.
* pnpm --filter client dev — запускает команду dev только внутри папки client.
Теперь, набрав в корне pnpm dev, вы запустите всё приложение целиком!
Заключение
Мы проделали большую работу. Мы не написали бизнес-логику, но мы создали профессиональный стапель, на котором будем строить наш корабль. У нас есть:
В следующей статье мы начнем создавать базу данных и подключим её к нашему Nest.js приложению.