Почему я не буду использовать Next.js

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

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

Существует множество «современных» фреймворков. И даже если сейчас перед вами этот выбор не стоит, вы можете задуматься, освоением какого лучше заняться, чтобы повысить свои профессиональные качества и продуктивность в будущем.

С момента выхода Remix в 2020 году я использовал именно этот фреймворк. Мне он настолько понравился, что на следующий год я устроился в эту компанию, чтобы помочь с развитием сообщества, а через 10 месяцев ушёл работать в EpicWeb.dev, где теперь обучаю людей всему необходимому для создания фулстек-приложений. И Remix играет в этом значительную роль, являясь веб-фреймворком, который аналогично Next.js нацелен на решение задач, связанных с созданием веб-приложений.

Поскольку Next.js аналогичен Remix, многие спрашивают, почему для преподавания фулстек-разработки в EpicWeb.dev я предпочёл именно Remix. И текущая статья станет ответом на этот их вопрос.

Мне нравится акцентировать внимание на положительной стороне разработки ПО. Я бы с бо́льшим рвением написал статью «Почему я использую Remix», изложив всё то, что мне нравится в этом фреймворке (и я уже так делал). Но многие люди просили меня написать конкретно о Next.js, так что эта статья для них.

И я не собираюсь здесь целенаправленно критиковать Next.js. Мне хочется просто выразить свою личную позицию и рассказать об опыте работы с ним. Если же вы не готовы читать об отрицательных сторонах этого фреймворка, то предлагаю вам остановиться и пойти развеяться.

Но прежде, чем приступать, должен признать, что сайт, на котором вы читаете эту статью (имеется в виду оригинал, — прим. пер.), создавался с помощью Next.js. Можете проверить это в консоли браузера, где найдёте глобальную переменную _NEXT_DATA_, а не _remixContext. Причина в том, что EpicWeb.dev разработан командой, которая долгие годы создавала ПО с помощью Next.js, и у них по этому поводу своё видение.

Мне же это даёт возможность сделать ещё одно важное заявление:

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

Не так важен выбор инструмента, как навык его использования для достижения желаемого результата — отличного пользовательского опыта.

В этой статье я объясню, почему считаю, что Remix лучше подходит для создания прекрасного пользовательского опыта, чем Next.js. Но это не означает, что, используя Next.js, вы допускаете ошибку или обязательно потерпите неудачу. Однако, на мой взгляд, Remix оказался бы для вас более удобен и наверняка повысил вашу продуктивность. В противном случае я бы даже не стал заморачиваться с написанием этой статьи.

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

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

Ну вот теперь можно приступать к объяснению причин, по которым я не буду использовать Next.js.

▍ Веб-платформа


Я более десяти лет развёртывал проекты через HTTP. Какое-то время я увлекался нативной разработкой (для десктопных и мобильных систем), но своё призвание нашёл именно в веб-среде. Хочу на примере небольшой истории объяснить, почему вам стоит хорошенько подумать о выборе фреймворка для веб-разработки.

Несколько лет назад я работал с React, в котором меня не устраивала стандартная утилита для тестирования, Enzyme. В итоге я написал собственную Testing Library, которая теперь является рекомендуемым инструментом для тестирования в React и прочих фреймворках UI.

Одно из основных отличий Enzyme и Testing Library в том, что первая даёт обёртку со множеством (чрезмерно) полезных (опасных) утилит для взаимодействия с отрисовываемыми элементами, а Testing Library предоставляет сами эти элементы. Если говорить в общем, то вместо обёртывания API платформы Testing Library предоставляет эти API.

И главное преимущество здесь в широкой применимости. Концентрируясь на стандартных API, Testing Library помогает людям знакомиться с этими API, что впоследствии оказывается полезным при работе где-либо ещё. При этом утилиты, доступные в других инструментах, опирающихся на стандартные API, интегрируются с Testing Library и наоборот без специального промежуточного ПО.

У каждой библиотеки, конечно, есть собственные API. И у Testing Library, к примеру, есть findByRole, для использования которого необходимо понимать входные данные. Но суть в том, что она работает непосредственно с DOM (Document Object Model, объектная модель документа), возвращая её узлы. Вместо того, чтобы обёртывать API, библиотека предоставляет эти API вам напрямую. В целом она прекрасно сочетает в себе полезность и широкую применимость.

А вот Next.js подобна Enzyme. Если Next.js содержит утилиты, позволяющие взаимодействовать с запросом, заголовками, куками и прочим, то в Remix все эти API доступны напрямую через функциональность loader и action. В Remix эти функции получают Request и возвращают Response. Если вам нужно понять, как вернуть JSON с некоторыми установленными заголовками, то вы обращаетесь к MDN (документация по веб-разработке), а не к документации Remix. И есть много таких примеров. Чем лучше вы осваиваете Remix, тем эффективнее работаете в веб-среде и наоборот.

Когда у Next.js были проблемы со сборкой статических сайтов, то вместо рекомендуемой к использованию директивы Stale While Revalidate HTTP-заголовка Cache Control они придумали сложную функциональность под названием Incremental Static Regeneration (ISR, поэтапная статическая регенерация), позволяющую добиться того же самого.

Когда я перешёл с Angular.js на React, то многое оставил позади. Тогда всё время, вложенное в освоение Angular, показалось для меня потраченным впустую. Я не хочу повторять подобные ошибки, поэтому предпочитаю выбирать такой фреймворк, который может не только дать мне всё необходимое с позиции пользовательского опыта, но также развить навыки, которые я смогу использовать в веб-разработке в целом.

▍ Независимость


Слышали об OpenNext? Если нет, то вот краткое описание:

OpenNext получает вывод Next.js и преобразует его в пакет, развёртываемый на любой платформе, работающей по шаблону FaaS (Function as a Service, функция как услуга). На данный момент поддерживается только AWS Lambda.

Но несмотря на все плюсы Vercel, это будет неудачный вариант, если вся ваша инфраструктура находится на AWS. Размещение на аккаунте AWS упрощает интеграцию с бэкендом. И это намного дешевле, чем использовать Vercel.

Next.js, в отличие от Remix или Astro, не может работать без стороннего сервера. Вы можете выполнять его как приложение Node. Хотя в этом случае работать всё будет не так, как в Vercel.

Стыковочное звено OpenNext необходимо, потому что Next.js тяжело развёртывать где-либо, кроме платформы Vercel. И тут я не берусь судить. Я ценю стремление компании сделать свой хостинг максимально привлекательным, но, очевидно, что это стремление помешало сделать Next.js удобным для развёртывания на любой платформе.

Я знаю, что команда Netlify потратила немало времени, чтобы получить поддержку Next.js и поспевать за изменениями этой библиотеки. Я понимаю, что и другие платформы хостинга создают промежуточные решения для поддержки фреймворков (Vercel управляет промежуточным ПО Remix). Но я неоднократно слышал со стороны этих платформ, что Next.js поддерживать особенно сложно.

NextJS можно легко запустить где угодно.

Это не так – я уже устал слышать подобные утверждения.

Они обесценивают всю утомительную работу, которую сообщество OpenNext проделывает, чтобы эта библиотека могла корректно работать вне Vercel.

Вот ещё один пример:


— Dax (@thdxr) 28 октября, 2023

Я также слышал от многих людей, что самостоятельно разместить проект Node.js в виде стандартного приложения невероятно проблематично. Интересно, что когда я впервые об этом написал, несколько человек сказали, что они просто забрасывают Next.js в контейнер и на этом всё. Проще простого. И я рад, что у них такой вариант прокатывает.

Но часть проблемы в том, что грань между Next.js и Vercel очень тонка. Поэтому, если вы развёртываете не на Vercel, то по факту используете не тот фреймворк, который указан в документации Next.js. И тут не всегда ясно, в чём отличие, так как в Vercel не заинтересованы тратить время на разъяснения.

Можно спорить о том, правы ли разработчики Vercel в выборе своего подхода. Но факт остаётся в том, что если их ценовая политика или нечто другое создают для вас проблемы, то уход от Vercel тоже окажется проблематичным. И снова причина в отсутствии мотивации.

Причём в последнее время по моим наблюдениям ценовая политика Vercel стала создавать сложности для многих.

Нам предложили заплатить $40k за ▲ (после того, как мы отказались платить 150k за корпоративный уровень), и это только за приложения со статическими активами, которые мы хотели переместить.

Наш текущий ежемесячный платёж на Cloudfront составляет 12$

— Закери Гризингер (@zackerydev) 26 октября, 2023

Аналогичная история. Нам предлагали платить по $4k/месяц за 'Vercel Secure Compute', так как для соответствия HIPAA нам нужно использовать VPC.

— Роланд Кирали (@kiralykek) 27 октября, 2023

Прибавьте сюда тот факт, что Vercel всё ещё, похоже, не приносит прибыли (даже после 8 лет активного роста, что ставит под сомнение их юнит-экономику). И если вы всерьёз задумываетесь поставить всё на эту лошадку, то сей факт должен вас насторожить.

С самого своего начала Remix создавался для развёртывания в любой среде, где работает JavaScript. И в значительной степени этому способствует упор на стандарты. Я определённо ценю этот его аспект.

Remix приобрела компания Shopify, которая прекрасно справляется с развитием проекта. После слияния команда Remix значительно ускорила темпы поставки ввиду большого разнообразия сред, в которых Shopify использует их продукт (торговые страницы, e-commerce, внутренние и внешние приложения и так далее). Кроме того, это слияние позволило команде Remix сосредоточить всё своё внимание на разработке фреймворка вместо того, чтобы искать способы заработать с его помощью денег.

▍ Next.js съедает React


Я всегда с опаской относился к компании Meta*, поэтому тот факт, что ей принадлежит React, тоже меня беспокоил. А поскольку в Vercel наняли многих членов команды React, то и здесь ситуация для меня не особо отличалась. С тех пор команда React стала намного менее дружной.

*Meta запрещена в России как экстремистская.

Лично я понимаю, что Vercel, похоже, стремится размыть границы между Next.js и React. Многие люди так и не понимают до конца, что из себя представляет Next.js, а что React, особенно в отношении функциональности Server Components и Server Actions.

Мне бы было куда спокойнее, если бы React принадлежала открытой компании. Но даже в текущей ситуации было бы здорово, если бы разработчики делали акцент на сотрудничестве, степень которого после объединения с Vercel существенно снизилась.

Думаю, здесь вы можете отметить, что этот пункт говорит в пользу Next.js, потому что её разработчики хотя бы пользуются преимуществами тесного сотрудничества с React. Но по своему опыту скажу, что избежание сотрудничества командой говорит не в пользу создаваемого ей ПО.
К примеру, для мейнтейнеров Redwood и Apollo недостаток сотрудничества создал серьёзную проблему.

Канареечные релизы React могут стабильно внедряться фреймворками вроде Next.js.

Честно: это утверждение – просто фиговый лист.

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

— Ленц Вебер-Троник (@phry) 28 октября, 2023

Обновлено: со мной связался Мэтт Кэрролл (developer advocate в команде React) как раз, когда я собирался опубликовать эту статью. Думаю, это добрый знак.

▍ Эксперимент на пользователях


Меня сильно беспокоят спорные решения команды Next.js, в частности решение преподнести экспериментальные фичи как стабильные. Функциональные возможности, которые Next.js позиционирует как стабильные, в React находятся на стадии канареечного релиза. Честно говоря, это одновременно и смешно, и грустно…

Вам известно, кто такие «канарейки»? Они относятся к сентинельным видам животных, используемым для предупреждения людей о грядущей опасности». То есть в Next.js встраивается канареечная функциональность, которая позиционируется как стабильная, после чего рассылается по всем пользователям, превращая ваше приложение в сентинельное. Для вас это может выглядеть иначе и, возможно, это лишь проблема обмена сообщениями, но я неоднократно слышал о сложностях, связанных с работой App Router в Next.js. Думаю, что основная причина как раз в незавершённости этой функциональности.

И хотя некоторые люди довольны работой App Router, я считаю, что в основном это следствие избавления от тяжести каталога pagesи получения вложенной маршрутизации, а не обязательно этими канареечными возможностями.

Да, React Server Components реально очень крутые, и я планирую использовать их, как только они будут готовы к продакшену (это позволит Remix снять значительную часть нагрузки).

Более развёрнуто эти проблемы раскрывает следующий пост:

React рекомендует:

— вам следует использовать совместно с React фреймворк;
— фреймворки должны подключаться к канареечной версии React, чтобы задействовать последние «стабильные» возможности, ещё не включённые в стабильный релиз.

Не представляю, как это сработает в Remix…

— Майкл Джексон (mjackson) 28 октября, 2023

▍ Слишком много магии


Слышали о принципе наименьшего удивления? Он звучит так:

Компонент системы должен действовать так, как этого ожидает большинство пользователей, а значит не удивлять их и не вызывать недоумение.

Этот принцип, пожалуй, можно было бы назвать принципом «веб-платформы», так как лучший способ избежать удивления пользователей — это максимально следовать API веб-платформы и сокращать масштабы «магии», которую ваше ПО творит поверх них. Магия — это здорово, и она может, к примеру, уменьшать количество шаблонного кода, но я хочу знать секреты этой магии, чтобы понимать, что происходит, а не просто наблюдать её действие.

И Next.js во многом нарушает этот принцип. К примерам можно отнести решение переопределить глобальную функцию fetch, чтобы она добавляла автоматическое кэширование. Лично для меня это огромный красный флаг. И именно подобные решения заставляют меня приостановиться и задуматься, а какие ещё удивительные вещи ждали бы меня в Next.js, возьмись я использовать эту библиотеку.

Большинство из нас со времён MooTools усвоили, что переопределение встроенных фич платформы ведёт к проблемам (поэтому мы и используем String.prototype.includes вместо String.prototype.contains). Подобные приёмы отрицательно влияют на будущее веб-платформы. И это также означает, что когда вы займётесь отладкой чего-либо, то вам придётся перелопатить доступные ресурсы в поиске «версии fetch для Next.js», а не для веб-платформы.

▍ Сложность


Я то и дело слышу, что Next.js для многих оказывается излишне сложным. Этот аспект также можно отнести к «излишней магичности». В React есть Server Actions, а также экспериментальный API taint, ставший объектом многих шуток.

Я высоко оценил затею разработчиков React добавить встроенную поддержку мутаций. Но меня определённо беспокоит их изменение семантики работы веб-форм. Всё это лишь повышает уровень сложности инструмента.

Я очень ценю, что команда Remix управляется людьми, которые разделяют мои принципы. Уверен, они обеспечат, чтобы добавление подобной функциональности не привело к излишнему усложнению работы с фреймворком. По факту команда Remix нацелена на сокращение площади API, а не её увеличение. И отсюда проистекает следующий аспект.

▍ Стабильность


Next.js уже находится на версии 13. React Router (созданный той же командой, что создавала Remix) существует гораздо дольше, но достиг всего лишь версии 6. Remix почти два года оставался на версии 1, и только месяц назад подрос до 2. И этот релиз старшей версии, благодаря упору команды на стабильность, стал самым занудным за всю историю различных фреймворков.

Должен признать, что команда Next.js усердно постаралась с помощью инструмента codemod упростить апгрейд библиотеки. И мне нравится, что фреймворк стремится к развитию. Но я также слышал много жалоб на нестабильность функциональности, добавленной в Next.js 13. Никак не смирюсь с внедрением канареечных фич под видом стабильных.

Ранее в этом году команда Remix рассказала о своих планах выпустить функциональность версии 2 в виде дополнения к версии 1, используя стратегию «Future Flags». Эта идея отлично сработала, и меньше, чем за день было обновлено огромное число активно разрабатываемых приложений.

Команда Remix заботится о стабильности. Именно поэтому в своё время они не последовали общему тренду и не стали реализовывать поддержку React Server Components, хотя их об этом очень просили. По той же причине за 8 лет существования React Router в этом компоненте произошло всего одно кардинальное изменение.

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

▍ Потенциал


Возможно, вы ожидали, что эта статья станет сравнением функций и возможностей Next.js с возможностями других фреймворков вроде Remix. Но суть в том, что вы можете создавать прекрасные вещи с помощью и того, и другого. Я лишь хочу показать, что функциональность библиотеки менее значима, чем её потенциальные возможности. Лично я чувствую, что Remix предоставляет гораздо больший потенциал для успеха в сравнении с Next.js, но аргументы в пользу этого расписывать не стану. Дело в том, что многое здесь является субъективным видением.

Когда команда Remix переписала демо-функциональность e-commerce из Next.js, чтобы ответить на вопрос «Remix vs Next.js», им удалось прекрасно показать, что Remix обеспечивает более качественный пользовательский опыт при меньшем объёме кода (что является важным аспектом). С тех пор разработчики Next.js обновили свой продукт, задействовав в нём App Router (который с их слов является стабильным, хотя опирается на канареечную функциональность), так что наверняка есть смысл провести очередное сравнение. С момента выхода той статьи в Remix тоже были внесены кое-какие доработки вроде потоковой передачи не по порядку (out-of-order streaming).

▍ Заключение


Вы можете согласиться с изложенными мной идеями или нет. Кому-то может показаться, что мой анализ был несправедлив. Возможно, вы бы предпочли, чтобы я описал все эти нюансы более развёрнуто или наоборот. Так что приглашаю всех желающих поделиться своими мыслями в X (ex-Twitter), на YouTube, в Twitch и так далее. Только помните, если вы оспорите мой опыт, то также оспорите и опыт многих людей, кто искренне согласился с изложенным в этой статье видением.

Ли Робинсон (вице-президент направления DX в Vercel) опубликовал развёрнутый ответ на эту статью, который многим будет интересно почитать. В нём он затрагивает немало из обозначенных мной проблем, но никакого конкретного решения для них не приводит.

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

Если коротко, то я считаю оба этих фреймворка достойными, но Remix намного лучше согласуется с моим представлением о том, каким должно быть легко поддерживаемое ПО, обеспечивающее удобство работы при реализации длительных проектов. Кроме того, если рассматривать эти два фреймворка, то программа EpicWeb.dev обеспечит вас бо́льшим багажом передаваемых знаний, чем в случае освоения Next.js.

Летом 2023 года я разместил в сети 8-недельную серию мастер-классов с EpicWeb.dev. Спустя несколько месяцев, одна из их участниц, Гвен Шапира, поделилась:

… Сейчас я веду разработку преимущественно с помощью стека NextJS и по-прежнему чувствую, что ваши занятия сформировали у меня ментальную модель, которая позволила ускорить темпы собственного развития и повысила чувство компетентности.

Главное — это правильный фундамент.

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

Ведь в конечном итоге я лишь хочу сделать мир лучше, научив вас создавать качественное ПО.

Узнавайте о новых акциях и промокодах первыми из нашего Telegram-канала
Источник: https://habr.com/ru/companies/ruvds/articles/771472/


Интересные статьи

Интересные статьи

Отфильтровав для Вас большое количество источников и подписок, сегодня собрал все наиболее значимые новости из мира будущего, машинного обучения, роботов и искусственного интеллекта за последнее время...
«Когда-то небольшой английский стартап был простой игрушкой для сборки PoS-терминалов. Затем — компонентом для умных датчиков, connected- и более сложных embedded-устройств, где без операционной сис...
Привет, друзья! Хочу поделиться с вами заметками о Next.js (надеюсь, кому-нибудь пригодится). Next.js — это основанный на React фреймворк, предназначенный для разработки веб-приложений, обладающ...
Развертывание машинного обучения (machine learning, ML) в продакшн – задача нелегкая, а по факту, на порядок тяжелее развертывания обычного программного обеспечения. Как итог, большинство ML ...
Памятка от редактора В прошлой статье мы рассказали про релиз панели управления Voximplant, не забыв упомянуть обновленную IDE. Сегодня мы посвящаем этому инструменту отдельный лонгрид – наша ко...