tgoop.com/super_oleg_dev/190
Create:
Last Update:
Last Update:
Разберем предметно почему считаю это проблемами.
Про синглтоны.
Допустим, у нас кастомный SSR (специально спустимся на уровень ниже), на сервере делаем запросы, используем полученные данные для рендеринга контента.
Кроме этого, часто нужно много других возможностей - работа с куками, заголовками и статусом ответа, мета-тегами, в общем все то что упрощают для нас мета-фреймворки.
Мой любимый пример, для работы с cookies на сервере, нужен соответствующий объект запроса. Для удобства и переиспользования логики, можно выделить отдельный сервис для работы с куками. Этому сервису потребуется объект Request.
Представим в виде псевдо-кода:
class Cookies {
constructor(request) {}
get() {}
set() {}
}
Так как запросов один сервер обрабатывает много, мы не можем сделать синглтон вида
export const cookies = new Cookies(request)
- request будет доступен только в обработчике запроса, экземпляр сервиса надо создавать каждый раз новый.Отдельно обсудим попозже как Next.js это все-таки реализует.
Передать созданный на запрос сервис в React компоненты не проблема - у нас уже будет код который на каждый запрос рендерит в строку некий рутовый
<App />
компонент, и инстанс cookies
можно передать через контекст.Но почему вообще мы должны работать с куками в компонентах? Для запросов и прочей логики приложения нам нужен механизм для сайд-эффектов - в разных фреймворках это loaders / actions / async components и так далее. Именно в таких лоадерах нам понадобится сервис.
Представим лоадер с использованием сервиса в виде псевдо-кода:
async function loader(params) {
return api.getSomething().then((response) => {
cookies.set(foo, response.someUniqueField)
return response
})
}
Какие тут варианты получить
api
или cookies
кроме импорта синглтона? Только интеграция с нашим SSR, и например передавать их в аргументы лоадера - const { api, cookies } = params
в данном случае (например так позволяет сделать Remix).Приложение растет, сервисов десятки, между ними много зависимостей - удобно ли это, гибко, масштабируется? Даст ли подходящий совет документация React?
Импорт
cookies
и headers
в Next.js возможен только за счет использования Async Local Storage - и это очень подходящее использование технологии, но по аналогии с этими объектами, сможете ли вы как-то просто добавить свои сервисы для Next.js приложения?Я уверен, что лучшее решение для кейса это механизм Dependency Injection, что уже давно широко используется на практике в JS экосистеме, например в Nest.js и Angular.
Но в React экосистеме это не популярная тема. Из последнего интересного, твит от одного из ведущих разработчиков фреймворка, что DI в React стоит делать через "exports" в package.json - https://x.com/sebmarkbage/status/1765828741500981475 - и хотя это интересная мысль, она закрывает только часть кейсов который может закрыть полноценный DI контейнер.
Также DI позволит радикально улучшить кодовую базу мета-фреймворков - сейчас в Next.js / Remix вы можете видеть огромные файлы с лапшой кода, которые реализуют сразу множество фичей. И такие же суровые Pull Request'ы, в которых эти файлы шатают.
Любое расширение этих фреймворков со стороны тоже как правило большая боль, потому что официальных точек расширения нет, помимо ручной конфигурации сборщика.
Даже без DI, пример фреймворка с плагинной архитектурой, у которых с расширением дела гораздо лучше - Nuxt.js.
Можно сравнить любой плагин, например PWA, для Next и для Nuxt:
- у Некста можно пошатать конфиг, обернуть рутовый компонент
- у Nuxt можно вклиниться на разные этапы жизненного цикла приложения, модифицировать и параметры билд тайма, и рантайма
BY SuperOleg dev notes
Share with your friend now:
tgoop.com/super_oleg_dev/190