Главная / Статьи

Уроки, полученные при развертывании SaaS на Next.js и создании CLI-инструмента для сборки проектов

Объясняются основополагающие решения — выбор стека технологий, механизмы аутентификации, поддержка нескольких арендаторов, система оплаты и управление состоянием — а также создание CLI-инструмента, упрощающего настройку проектов Next.js.

6 мин чтения1331 слов

Разработка настоящего SaaS-продукта с использованием React и Next.js — это не столько выбор модной библиотеки, сколько правильное принятие десятков незаметных решений ещё до того, как вы вообще начнёте работать с панелью управления. Та же дисциплина, которая позволяет архитектуре продукта выдерживать нагрузку реальных клиентов, проявляется даже в такой обыденной задаче, как создание нового проекта на Next.js — именно поэтому встроенный инструмент командной строки для генерации шаблонов учит того же, что и само создание SaaS: именно скучная настройка определяет успех или неудачу проекта.

Выбор технологий, которые не замедлят вас

После выпуска более одного SaaS-продукта технологический стек обычно принимает предсказуемую форму:

  1. Next.js в качестве единственной фреймворковой среды для маршрутизации, серверной отрисовки и API-маршрутов, что позволяет избежать необходимости использования разных инструментов для каждой задачи.
  • TypeScript — обязательно, особенно там, где реализована логика оплаты; это не те ошибки, которые хочется видеть во время работы программы.
  • Tailwind CSS для стилизации, в первую очередь потому, что он избавляет от постоянной борьбы с проблемой специфичности CSS.
  • Redux Toolkit или Zustand — используются исключительно для состояний, которые действительно нуждаются в глобальном обмене между компонентами.
  • Ни один из этих выборов сделан не ради новизны. Вместе они позволяют небольшой команде работать быстро, не накапливая при этом технический долг, который невозможно будет погасить.

    Сначала создайте простые основы

    У основателей бывает соблазн сразу приступить к созданию панелей управления. Сопротивляйтесь этому желанию. Прежде чем создавать что-либо, предназначенное для пользователей, сначала наладите следующие три аспекта:

    1. Аутентификация — реализуется с использованием настоящих сессий, а не просто токенов, сохраняемых в localStorage.
    2. Многоклиентская архитектура — даже если сейчас у вас только один клиент, проектируйте решение с возможностью обслуживания нескольких клиентов с самого начала.
    3. Хуки для выставления счетов — заранее настроение webhook-ов Stripe позволяет избежать сложной переработки после запуска продукта.

    Вот шаблон, который стоит использовать для выполнения API-запросов в рамках конкретного клиента без необходимости повторять код:

    // hooks/useTenantFetch.ts
    import { useCallback } from "react";
    import { useSession } from "next-auth/react";
    
    export function useTenantFetch() {
      const { data: session } = useSession();
    
      const fetchScoped = useCallback(
        async (endpoint: string, options: RequestInit = {}) => {
          if (!session?.tenantId) throw new Error("No active tenant");
    
          const res = await fetch(`/api/${session.tenantId}${endpoint}`, {
            ...options,
            headers: {
              ...options.headers,
              "Content-Type": "application/json",
            },
          });
    
          if (!res.ok) throw new Error(`Request failed: ${res.status}`);
          return res.json();
        },
        [session]
      );
    
      return { fetchScoped };
    }
    

    Это небольшой утилитный инструмент, но он спасает от необходимости распространять проверки идентификаторов клиентов по десяткам компонентов позже.

    Понимание того, что должно находиться в глобальном состоянии

    Не каждый фрагмент данных заслуживает места в Redux. Один из инженеров, работающий в стартапе, поддерживаемом Y Combinator, хорошо это сформулировал: глобальное состояние — это долг, который со временем начинает приносить проценты. Используйте Redux (или любой другой выбранный вами глобальный хранилище) исключительно для тех элементов, которые действительно касаются всего интерфейса — модалок, флагов функций, предпочтений пользователей — а остальное, что на самом деле является просто серверными данными в оболочке интерфейса, пусть обрабатывает React Query или SWR.

    Несколько ключевых выводов кратко описывают аспекты создания SaaS-приложений:

    • Сначала наладите аутентификацию и систему оплаты, прежде чем вкладывать средства в отлаженный интерфейс.
    • Типизация на TypeScript перестаёт быть необязательной, как только начинаются финансовые вложения.
    • Избегайте чрезмерной централизации состояния; большинство функций должны находиться в инструментах управления серверным состоянием, а не в глобальном хранилище.

    Всё это не связано с стремлением использовать самую новую библиотеку. Оно основано на фундаментальных принципах: заранее урегулируйте вопросы аутентификации, работы с тенантами и финансового учёта, и всё остальное — рост проекта, добавление новых функций, масштабирование — станет гораздо проще реализовывать на этой основе.

    Когда сама настройка становится узким местом

    Именно желание избавиться от повторяющейся и подверженной ошибкам работы по настройке в конечном итоге приводит к автоматизации самих стандартных шагов. Каждый фронтенд-разработчик знает эту рутину: сначала создаётся структура нового проекта с помощью create-next-app, а затем начинается сама утомительная работа. Необходимо создать папку components, разделить содержимое ui и features, настроить hooks, связать общие types, написать вспомогательные функции, настроить псевдонимы путей и организовать иерархию папок — и может пройти целый час, прежде чем будет написана хотя бы одна строка настоящей бизнес-логики.

    После многократного выполнения этого ритуала естественным следующим шагом стало его автоматизирование, в результате чего появился первый опубликованный пакет с открытым исходным кодом для npm: nexarch-cli.

    Основная проблема

    Стандартные шаблоны старта Next.js предоставляют пустую основу, а не архитектуру, готовую к использованию в производстве. Современные приложения обычно требуют:

    • Четкого разделения логики отображения и бизнес-логики
    • Модульной структуры, основанной на функциях
    • Масштабируемых определений типов и утилитных оберток
    • Единообразных правил, которым может следовать вся команда

    Повторное создание всего этого вручную для каждого прототипа или проекта клиента занимает много времени, сопровождается неоднородностью и подвержено ошибкам.

    Что на самом деле делает nexarch-cli

    nexarch-cli — это интерактивный инструмент командной строки, предназначенный для быстрого создания чистой, модульной архитектуры Next.js в течение нескольких секунд. Вместо ручного создания вложенных папок и файлов-заглушек достаточно ответить на несколько вопросов в терминале, и инструмент сам настроит базовую структуру.

    Основные его функции включают:

    • Интерактивное создание структуры с помощью простых вопросов в терминале, адаптированных под ваши потребности.
    • Модульная архитектура с заранее настроенными конвенциями, позволяющими масштабироваться по мере роста приложения.
    • Отсутствие необходимости в глобальной установке — инструмент запускается по требованию с помощью npx.
    • Соответствие современным конвенциям Next.js и React, что обеспечивает согласованность структуры каталогов с современными практиками.

    Запуск инструмента

    Нет необходимости устанавливать что-либо глобально. Вы можете запустить его напрямую:

    npx nexarch-cli
    

    После ответов на вопросы структура вашего проекта будет сгенерирована и готова к фактической разработке.

    Создание и публикация этого инструмента в качестве первого инструмента для разработчиков сопровождались сложным процессом обучения. Несколько важных уроков:

    • Интерфейс терминала так же важен, как и сам код. Корректная обработка завершения процессов, четкое отображение запросов и ясные сообщения об ошибках имеют такое же значение, как и логика генерации файлов.
    • Операции с файловой системой скрывают множество неочевидных случаев. Написание рекурсивных функций для создания каталогов и шаблонов файлов, которые будут корректно работать на разных операционных системах, требует тщательного и многократного тестирования.
  • Упаковка для npm имеет свою собственную ступеньку обучения. Правильная настройка бинарных файлов package.json (bin), работа с правами доступа к файлам с помощью chmod и поддержание минимального уровня нагрузки от зависимостей позволяют понять, как на самом деле работают инструменты командной строки на основе Node.
  • Текущее состояние проекта

    Этот инструмент по-прежнему находится на ранней стадии развития как проект с открытым исходным кодом, и ему полезен внешний вклад на этапе формирования. Код хранится по адресу github.com/CaffeineLogs/nexarch-cli, а опубликованный пакет можно найти в реестре npm под именем nexarch-cli.

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

    Независимо от того, решаете ли вы, что должно входить в Redux, или как следует организовать новый проект на Next.js, один урок остается неизменным: те части проекта, которые кажутся наиболее сложными — аутентификация, управление тенантами, оплата, структура папок — именно те элементы, которые важно правильно настроить, а часто и автоматизировать, прежде чем переходить к чему-либо ещё.