Сервис развивается: тестируем формат, собираем идеи, улучшаем сервис. Есть идеи? Написать
Дайджесты новостей
Архитектурная иллюстрация редизайна стартовых шаблонов AdonisJS с четырьмя независимыми макетами и строгой типизацией форм.

Редизайн стартовых шаблонов AdonisJS: темная тема, типизированные формы и компонентные лейауты

Когда команда начинает новый full-stack проект на Node.js, перед ней почти всегда встает неприятная дилемма. Либо собирать фундамент с нуля, тратя недели на стыковку маршрутизации, аутентификации и сборщика, либо брать готовый шаблон «все в одном». Второй путь кажется быстрее, но часто оборачивается кошмаром: шаблон перегружен лишними библиотеками, стили написаны под конкретный фреймворк, а вычищение ненужного кода отнимает больше времени, чем написание собственного сервиса.

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

Отказ от швейцарского ножа в пользу четырех сценариев

Вместо единственной универсальной заготовки команда AdonisJS переработала пять наборов: hypermedia для классического серверного рендеринга на шаблонизаторе Edge.js, inertia-react и inertia-vue для монолитных SPA-интерфейсов, а также чистые api и api-monorepo.

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

  • Marketing: легкий макет с плавающей шапкой и подвалом для посадочных страниц и документации;
  • Auth: двухколоночный экран для входа и регистрации, изолированный от общей навигации;
  • App: защищенная рабочая среда пользователя с боковой панелью и профилем;
  • Settings: вложенный макет с дополнительной навигацией по вкладкам конфигурации аккаунта.

Каждый макет существует независимо, избавляя компоненты страниц от громоздких оберток и условных операторов.

Почему темная тема больше не ослепляет при загрузке

Классическая беда многих интерфейсов с темной темой — мерцание светлого фона (FOUT) в момент открытия страницы. Браузер получает белый HTML, запускает клиентский JavaScript, считывает значение из хранилища браузера и лишь затем перекрашивает фон в темный цвет. В темной комнате эта доля секунды воспринимается как неприятная фотовспышка.

AdonisJS устранил этот дефект на серверном уровне. Предпочтение темы сохраняется в cookie. Серверный middleware считывает этот параметр до начала рендеринга и подставляет атрибут data-theme прямо в тег html отправляемой страницы. Браузер сразу рисует интерфейс в нужной палитре.

При этом разработчики полностью отказались от сторонних CSS-каркасов вроде Tailwind. Вся визуальная система построена на семантических CSS-токенах в заголовке стилей: переменные --paper, --ink, --line и --btn инкапсулируют цвета фона, текста, разделителей и кнопок. Переключение темы меняет только значения токенов, делая стилизацию предсказуемой и легковесной.

Сквозная типизация: как схема VineJS защищает верстку от опечаток

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

Связка библиотеки @adonisjs/inertia пятой версии и Inertia v3 решила эту задачу за счет сквозной типизации. Новый компонент Form выводит типы полей, структуру данных и возможные ошибки напрямую из серверной схемы компилируемого валидатора VineJS.

Контроллер на бэкенде объявляет строгую схему входящего запроса:

import vine from '@vinejs/vine'

// Серверная схема валидации данных аутентификации
export const loginValidator = vine.compile(
  vine.object({
    email: vine.string().trim().email().normalizeEmail(),
    password: vine.string().minLength(8),
    rememberMe: vine.boolean().optional(),
  })
)

На фронтенде компонент формы связывается с маршрутом обработчика. Если разработчик попытается обратиться к опечатанному ключу errors.emial, компилятор TypeScript мгновенно выдаст ошибку сборки:

import { Form } from '@adonisjs/inertia/react'
import AuthLayout from '~/layouts/auth_layout'

export default function LoginPage() {
  return (
    <Form route="session.store">
      {({ errors, processing }) => (
        <fieldset disabled={processing}>
          <label htmlFor="email">Электронная почта</label>
          <input id="email" name="email" type="email" aria-invalid={Boolean(errors.email)} />
          {errors.email && <span className="error">{errors.email}</span>}

          <label htmlFor="password">Пароль</label>
          <input id="password" name="password" type="password" />
          {errors.password && <span className="error">{errors.password}</span>}

          <button type="submit">{processing ? 'Проверка...' : 'Войти'}</button>
        </fieldset>
      )}
    </Form>
  )
}

// Декларативное назначение изолированного макета авторизации
LoginPage.layout = [AuthLayout]

Когда стоит переходить на новые наборы

Свежий релиз стартовых наборов AdonisJS под капотом опирается на актуальный стек: Vite 8.3, React 19.3 или Vue 3.5.43, а также ESLint 10.11.

Главный компромисс обновления — глубокая интеграция с VineJS. Если в вашем проекте уже используется другая библиотека валидации (например, Zod), компонент Form потребует адаптеров. Однако для команд, создающих надежные full-stack приложения на экосистеме AdonisJS, эти шаблоны дают идеальную стартовую точку без лишнего визуального шума и с бескомпромиссной защитой типов от базы данных до кнопки отправки.