Всем привет! Меня зовут Михаил, и я являюсь СТО в одной IT компании. Сегодня я хочу кратко рассказать вам о мотивах создания собственной библиотеки для разработки React-приложений с поддержкой SSR (серверный рендеринг) и поделиться результатами этой работы.
Как известно, великие дела начинаются с малого. В нашем случае у нас было небольшое количество React-приложений без поддержки SSR, которые в конечном итоге требовали перехода на серверный рендеринг. Поскольку навигация в обычных React-приложениях (SPA, CRA) осуществляется с помощью библиотеки react-router (по большей части), мы стремились найти решение, которое позволило бы нам запустить существующие приложения с минимальными изменениями для SSR. На рынке было немного решений для SSR в React с использованием react-router. Next.js не подходил из-за своей системы маршрутизации и некоторых особенностей. В конечном итоге мы наткнулись на фреймворк под названием after.js, который позволил нам воплотить наши идеи. Однако со временем мы столкнулись с вызовом: React и связанные библиотеки существенно обновились, тогда как after.js остался на месте. В добавок появление такой вещи как паралелизм не оставило нас равнодушными. Несмотря на то что решение набрало значительное количество звезд на GitHub, его разработку прекратили.
В виду отсутствия подходящих альтернатив и на основе анализа текущих тенденций, мы приняли решение разработать собственный фреймворк, используя самые новые технологии и решая старые проблемы. Стоит отметить, что мы положительно относимся к Next.js и Vite SSR Plugin, которые предлагают отличный опыт разработки приложений с поддержкой SSR. Тем не менее, их система маршрутизации не соответствовала нашим требованиям. Главной целью было обеспечить, чтобы при переходе от обычного приложения на React к SSR (и наоборот) практически ничего не требовалось менять, и разработанное приложение можно было запускать как в режиме SSR, так и в режиме SPA.
Так появился - Vite SSR BOOST. Изначально задумывался как плагин, но постепенно вырос в полноценную библиотеку.
Ключевые особенности Vite SSR BOOST:
Разработка приложений как с поддержкой SSR, так и в режиме SPA (CRA).
Возможность переключения между режимами SSR и SPA в любое время.
Создание сборок без изменений для работы в режиме SSR или SPA.
Использование библиотеки react-router для навигации.
Вся мощь Vite.
Поддержка рендеринга в поток (rendertopipeablestream).
Поддержка Suspense.
Базовые знания Node.js и React Router вполне достаточны. Вот краткий пример страницы приложения (это работает практически одинаково и в SSR и SPA режимах без каких либо изменений в коде):
import { Suspense} from '@lomray/consistent-suspense';
import type { FCRoute } from '@lomray/vite-ssr-boost/interfaces/fc-route';
import { Link, useLoaderData } from 'react-router-dom';
import UserPlaceholder from './components/placeholder';
import User from './components/user';
interface ILoaderData {
userIds: string[];
}
/**
* Just simple page which render short info about 3 users by id's
*/
const DetailsPage: FCRoute = () => {
const { userIds } = useLoaderData() as ILoaderData;
return (
<>
<p>
Header
</p>
<p>
Load users for id's: {userIds.join(', ')}
</p>
<div>
<Suspense fallback={<UserPlaceholder count={2} />}>
<>
<Suspense.NS>
<User userId="user-1" />
</Suspense.NS>
<Suspense.NS>
<User userId="user-3" />
</Suspense.NS>
</>
</Suspense>
<Suspense fallback={<UserPlaceholder />}>
<User userId="user-2" />
</Suspense>
</div>
<p>
Footer
</p>
</>
);
};
/**
* Just example (react-router API)
*/
DetailsPage.loader = (): ILoaderData => {
const userIds = ['user-1', 'user-2', 'user-3'];
return { userIds };
};
export default DetailsPage;
Конечно, в процессе разработки нас ожидали значительные трудности. Тем не менее, как гласит поговорка: "то, что не убивает, делает нас сильнее". Теперь вместо тысячи слов я хотел бы представить вам демонстрационный репозиторий приложения с запущеным приложением в 2х режимах (кому сразу хочется посмотреть демо запущеного приложения в режиме SSR - вот ну или в режиме SPA - вот), где помимо самой библиотеки были решены несколько связанных проблем разработки (управление мета данными при rendertostream, генерация стабильных id внутри Suspense и др.).
Мы с удовольствием выслушаем ваши мысли и получим обратную связь — для нас это отличный стимул. Спасибо за внимание.