Next.js: Использование с React Router 4

Созданный на 5 апр. 2017  ·  122Комментарии  ·  Источник: vercel/next.js

Можно ли использовать next.js с новым маршрутизатором реакции v4?

Самый полезный комментарий

@timneutkens, добавивший интеграцию с

Все 122 Комментарий

@Knaackee Вы попробовали эту возможность? Мне тоже интересно, заставил ли кто-нибудь работать с любой версией RR?

Дальше свой роутер, зачем использовать RR?

@sergiodxa Параметры взвешивания при

@oyeanuj 🤔 вы можете постепенно перейти на Next, просто установите Next.js для обработки 1 маршрута и используйте прокси, чтобы иметь как ваше текущее приложение, так и приложение Next.js, затем переместите второй маршрут с RR на Next.js, и это способ сохранить текущее приложение во время миграции, в конечном итоге у вас будет все в Next.js

Глядя на примеры, кажется, что next имеет одну таблицу маршрутов, такую ​​как RRv2-3, и не поддерживает «вложенные маршруты», такие как RRv4. Это хорошо.

Я бы попробовал использовать RR, или есть серьезная оговорка, о которой я не знаю?

@igl Вы придумали решение?

Новая парадигма вложенных маршрутов react-router 4 кардинально меняет правила игры и является обязательной частью нашего текущего проекта. Мне интересно, удалось ли кому-нибудь заставить rr4 работать с next.js?

MemoryRouter работает, если не так ...
В противном случае динамические компоненты могут быть только клиентскими, где HashRouter отлично работает ...

const AdminPage = dynamic(
  import('..../AdminPage'),
  { ssr: false }
);

Я также следую подходу react-router а весь контент, отображаемый сервером, с помощью маршрутизатора next .

@malixsys @pegiadise не могли бы вы подробнее рассказать, как использовать следующий маршрутизатор и реагирующий маршрутизатор вместе?

Вы можете установить флаг в componentDidMount и условно отобразить <Router /> когда флаг истинный. ( componentDidMount не работает на сервере 😉)

Фактически, мы скоро включим React Router в Next.js :)
- https://twitter.com/rauchg/status/948318111828099072

Это все еще происходит? Я вижу примечания к выпуску V6 canary, но о нем нет ни слова.

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

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

@timneutkens, добавивший интеграцию с

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

Одна и та же.

Можем ли мы хотя бы повторно открыть эту проблему, чтобы ее можно было отследить?

Я собираюсь снова открыть его, но обратите внимание, что это проект с

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

Функции, которые я представил в Next 6, на самом деле работают над поддержкой React Router.

У нас были другие приоритеты для Next 6, которые значительно улучшают надежность и масштабируемость Next.js, например, 100-кратное ускорение разрешения страниц, компонент приложения, выполнение следующего экспорта в разработке, babel 7 и т. Д.

Надеюсь, это дополняет мой предыдущий комментарий.

Итак, TLDR:

  • Мы сделаем это, но не сразу
  • В Next 6 внесено множество улучшений в различные части Next.js

Чтобы еще больше расширить комментарий @timneutkens : мы определенно хотим RR, но у нас нет каких-либо жестких ограничений в текущем маршрутизаторе, которые делают его приоритетным. Все возможные варианты использования маршрутизации успешно реализованы с помощью текущего API Next.js.

Есть две причины, по которым нам действительно нужна поддержка React Router :

  • Упростите нашу собственную кодовую базу Next.js, избавьтесь от необходимости поддерживать собственный маршрутизатор, сделайте все меньше и модульнее
  • Упростите путь миграции больших приложений, уже использующих RR

Таким образом, я согласен, что мы должны оставить этот вопрос открытым!

В противоположность этому, отсутствие response-router означает, что next хорошо работает с relay-modern, и было одной из причин, по которой мы перешли на next из нашего старого приложения response-router.

@merrywhether я работал над приложением RRv4 с relay-modern в прошлом году. Хотите быть более конкретным?
Я не помню, чтобы у нас были серьезные проблемы из-за этого.

@igl Это соответствует документации реле: https://facebook.github.io/relay/docs/en/routing.html#react -router-https-reacttrainingcom-react-router

Проблема в том, что компонентный подход RRv4 не допускает детерминизма на этапе предварительной компиляции, что может привести к возникновению водопадов запросов на клиенте.

@rauchg Из интереса, мое понимание маршрутизатора Next заключается в том, что он не поддерживает концепцию вложенной маршрутизации, поэтому вы можете сохранить внешнюю разметку во время навигации по странице. Вы знаете, есть ли способ сделать это возможным с помощью текущего маршрутизатора?

@dbbk проверьте наш пример приложения nextgram (https://github.com/now-examples/nextgram), он делает именно это

В следующих 5 мы выполняем «внешнюю разметку», имея компоненты макета верхнего уровня, которые расширяются на всех наших страницах: базовый макет имеет верхнюю навигацию, затем несколько вложенных макетов, которые расширяют базу для списков / деталей / и т. Д., А затем Компоненты наших страниц расширяют эти суб-макеты своим собственным конкретным содержанием. В следующих 6 вы также можете выполнить базовую «внешнюю разметку», используя _app.js я полагаю.

Будет ли следующая версия настраиваемой для выбора решения маршрутизации, отличного от React Router?

Привет, мне нужен только реактивный маршрутизатор, чтобы передавать реквизиты на страницы (используя <Route render ={} /> вместо <Route component ={} /> ), могу ли я сделать это с помощью Next?

См. Https://github.com/zachrbrown/next-react-router. Документов немного, но некоторые краткие объяснения можно найти в https://github.com/zachrbrown/next-react-router/blob/master/src/IsomorphicRouter.js.

Глядя на примеры, кажется, что next имеет одну таблицу маршрутов, такую ​​как RRv2-3, и не поддерживает «вложенные маршруты», такие как RRv4. Это хорошо.

Привет,

Означает ли это, что мне нужно создать одну страницу для одного маршрута?

Допустим, у меня есть 2 маршрута sign up , log in . У меня была бы 1 страница с таким же макетом, разница только в области форм. То есть мне просто нужно создать 1 файл в папке pages . Но со следующими маршрутами мне нужно создать 2 файла в папке pages . Это?

Если это так, то макет перемонтируется при каждой навигации, а не только в области форм, верно?

@ 7c78 Вы можете использовать _app.js для постоянного макета страницы для всех страниц. Еще нужно создать общие компоненты макета, которые можно повторно использовать на разных страницах, чтобы добиться того, что вы ищете:

// pages/login.js

class LoginPage extends React.Component {
  render() {
    return (
      <AuthForm>    // same component can be reused in signup
        <form>
          ...implementation of login
        </form>
      </AuthForm>
    );
  }
}

Кроме того, вы можете сделать то, что мы сделали недавно, и определить компоненты базового макета, которые все компоненты вашей страницы расширяют:

//layouts/baseAuth.js

class BaseAuth extends React.Component {
  abstract formContent();  // we use typescript, but you can have the same concepts
  abstract formSubmit():

  render() {
    return (
      <SomeStyledDiv>
        <form>
          {this.formContent()}
          {this.formSubmit()}
        </form>
      </SomeStyledDiv>
    );
  }
}

А затем вы просто расширяете BaseAuth на своих страницах входа и регистрации и определяете formContent и formSubmit в каждой из них (это игрушечные примеры, поскольку я не знаю ваших точных требований).

@merrywhether
В настоящее время я использую ваш подход, и следующие примеры тоже используют его.

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

С RRv4 у нас есть одна страница, а формы отображаются / перемонтируются на основе маршрутов (а не всей страницы). Маршруты - это просто компоненты.

Спасибо за быстрый ответ!

@ 7c78 Это верно в отношении перемонтирования, хотя я думаю, что узлы DOM используются повторно, поскольку vDOM переходит в то же состояние.

Это не то, о чем мы особо беспокоимся, потому что мы также не можем использовать response-router с relay-modern, поэтому нам пришлось использовать этот шаблон в любом случае.

@merrywhether я не уверен насчет vDOM, потому что сервер возвращает новый документ / html для каждого маршрута. Извините, проигнорируйте это предположение, я просто новичок.

Я согласен, что мы все равно должны использовать этот шаблон. Благодаря!

Вы можете использовать RR с next.js, поместив все ваше приложение в pages / index.js, но вы потеряете некоторые полезные свойства next, например, нестандартное разделение кода, и вам придется настраивать его самостоятельно.

Я был бы рад, если бы был рассмотрен Reach Router. Он очень похож на реактивный маршрутизатор и имеет ряд важных преимуществ:

  • Он решает некоторые важные проблемы, связанные с созданием ссылок и управлением фокусом (https://reach.tech/router/accessibility).
  • Весит меньше (на момент написания)

Маршрутизатор Reach Router тоже отличный 🥇

Динамические маршруты в стиле RR - хороший API, но статическая (и статически анализируемая) маршрутизация также дает много преимуществ. Ни один из подходов не является победителем слэм-данка.

@sorokinvj Это поддерживается только через плагин (в настоящее время) .. https://github.com/fridays/next-routes

статические ссылки настолько просты, что даже не поддерживают параметры в ссылках ...

Я использую сторонний пакет next-routes сейчас https://github.com/fridays/next-routes, чтобы обойти его

отправлено из моего Айфона

24 октября 2018 года в 23:01 Энди Инграм [email protected] написал:

Динамические маршруты в стиле RR - хороший API, но статическая (и статически анализируемая) маршрутизация также дает много преимуществ. Ни один из подходов не является победителем слэм-данка.

-
Вы получаете это, потому что подписаны на эту ветку.
Ответьте на это письмо напрямую, просмотрите его на GitHub или отключите обсуждение.

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

@merry, использую ли я также next-routes но предпочел бы, чтобы это было частью ядра Next.js.

Ты упомянул

Я считаю, что следующая команда работает над добавлением параметров пути ...

Мне любопытно, у вас есть ссылка на это? Возможно, открытый вопрос по параметрам маршрута? Я не могу найти его ... Возможно, плагин решит эту проблему, и это будет рекомендуемым решением в будущем.

@curran Источником был твит одного из разработчиков sapper.js, в котором говорилось, что следующий черпал вдохновение из sapper.js и реализовал маршрутизацию regex-filename-routing в будущей версии. Конечно, из-за того, что Twitter является тем, чем он является, я не мог найти оригинальный твит.

Эта проблема была поднята 5 апреля 2017 г., а сейчас 27 февраля 2019 г. Почти 2 года и нет решения
Может пора заменить недоделанный встроенный роутер на что-нибудь хорошее?

Ой. Это довольно оскорбительно для разработчиков NextJS, которые потратили много часов на решение маршрутизации.

Сначала мне не хватало ReactRouter. Теперь я даже не помню, что у NextJS был другой маршрутизатор, пока кто-нибудь мне не напомнит. Verbose Link API, например, тривиально обернуть с помощью прокси (в зависимости от ваших данных / архитектуры API). Делимся этим совершенно секретным: 😆

import _Link from "next/link"
export function Link({as, children, href}) {
  as = as || QS.parse(U.parse(href).query || "").url || null // QS, U are parsing libs
  return <_Link as={as} href={href}>
    {children}
  </_Link>
}
<Link as="/about" href="/page?url=/about"/> verbose
→
<Link href="/page?url=/about"/> ok

Я думаю, нам всем следует меньше тратить время на жалобы на второстепенные вещи 😉

@ ivan-kleshnin Приятно я добавил похожую обертку

В соответствии с предыдущим комментарием я хотел бы указать на https://www.contributor-covenant.org/version/1/4/code-of-conduct

Я скрыл указанный комментарий.

У меня нет проблем с next/router для большинства случаев использования.
Но это должно немного улучшиться в части universal routing .
В случае развертывания Now 2 я бы хотел просто взять now.json и использовать его для маршрутизации в моем приложении.

Если вы хотите внедрить RR4 в проект nextJs, вам нужно сделать 2 вещи:

  1. Предотвратить NextJS SSR, используя next/dynamic вы можете это сделать.
  2. Используя HashRouter вместо BrowserRouter ->, если пользователь перезагружает страницу, браузер может загрузить предыдущую страницу (не страницу 404)

Если вы хотите внедрить RR4 в проект nextJs, вам нужно сделать 2 вещи:

  1. Предотвратить NextJS SSR, используя next/dynamic вы можете это сделать.
  2. Используя HashRouter вместо BrowserRouter ->, если пользователь перезагружает страницу, браузер может загрузить предыдущую страницу (не страницу 404)

Спасибо за этот ответ, мне очень помогло.

@reach / router и response-router 5 объединяются: https://reacttraining.com/blog/reach-react-router-future/

Как это повлияет на next.js?

@ alp82 Поскольку Next.js по-прежнему не использует React Router или Reach Router, он вообще не повлияет на Next.js.

Мне нужна функция переключения маршрутов в nextjs для рендеринга компонентов нескольких страниц на страницах индекса.
так как я могу реализовать это в nextjs ....... ???

Если вы хотите внедрить RR4 в проект nextJs, вам нужно сделать 2 вещи:

  1. Предотвратить NextJS SSR, используя next/dynamic вы можете это сделать.
  2. Используя HashRouter вместо BrowserRouter ->, если пользователь перезагружает страницу, браузер может загрузить предыдущую страницу (не страницу 404)

если вы хотите повторно отобразить свою предыдущую страницу без ошибки 404, просто используйте этот маршрут получения в файле экспресс-сервера.

server.get ('ваши параметры', (req, res) => {
const actualPage = '/ ваша_страница'
const queryParams = {id: req.params.id}
app.render (req, res, actualPage, queryParams)
})

Я задокументировал подход к использованию next.js с react-router , предоставляя один файл сохраняя собственные функции

Я буду рад получить отзывы и улучшить то, что я сделал.

Документация доступна как:

Ура!

Я бы очень не одобрял включение response-router таким образом, поскольку в итоге вы получаете одну точку входа, что означает (чрезвычайно) более медленную разработку, более высокую вероятность доставки слишком большого количества кода на клиентскую сторону и меньшую видимость оптимизаций, таких как автоматический статический экспорт.

@timneutkens Может я ошибаюсь. Но при ленивой загрузке конфигурация маршрутизации представляет собой всего один файл конфигурации. Я не думаю, что здесь это повлияет на масштабируемость или производительность. Я бы хотел узнать об этом больше.
Преимущество response-router в том, что разработчики полностью контролируют код.

@timneutkens , я не стану здесь спорить, но прошу вас

@timneutkens, что касается упомянутых вами пунктов, это вопрос компромиссов. Моя - эксперимент, чтобы выяснить, как можно использовать Next.js с другой настройкой.

Слишком много кода на стороне клиента

Любой современный пакет может разбивать клиентские ресурсы на куски, и маршруты react-router самом деле являются очень удобными точками разделения.

Более высокое время сборки для разработчиков

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

Нет статического экспорта

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

У этой проблемы нет недостатка в решении. Например. все еще возможно вручную объявить список маршрутов для статического экспорта

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

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

Вы не можете ускорить загрузку во время разработки на основе вашего подхода, нет специальной тонкой настройки конфигурации веб-пакета, поскольку веб-пакет будет просто компилировать и отслеживать каждый отдельный маршрут, который вы импортируете, что значительно замедляет редактирование общих компонентов. Поэтому в Next.js есть записи по запросу: https://nextjs.org/blog/next-8#improved -on-demand-entries

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

Я не возражаю против того, чтобы скрыть комментарий, если он правильно отражает, что единственный раз, когда вы хотите его использовать, - это перенести приложение, которое уже использует response-router, а затем постепенно перейти на несколько страниц.

Привет @timneutkens
Можете ли вы посчитать некоторые из плюсов, которые дает возможность статического анализа и которые невозможны с решениями динамической маршрутизации?

Что-то вроде этого https://github.com/jaredpalmer/after.js ?

Я прочитал все комментарии и до сих пор не понимаю, будет ли RR4 + включен или необязателен в будущей итерации next.js. Это дорожная карта роутера или что-то подобное?

@laurencefass похоже, что нет плана поддерживать react-router (на сегодняшний день).

На мой взгляд, система маршрутизации Next.js становится достаточно зрелой, так что, вероятно, она нам (больше) не нужна :)

«На мой взгляд, система маршрутизации Next.js становится достаточно зрелой, так что, вероятно, она нам (больше) не нужна :)»

За исключением тех, кто хочет постепенно внедрять Next.js в существующую кодовую базу. Я думаю, что более полезное обсуждение, вероятно, будет не «Маршрутизация Next.js против маршрутизации реактивного маршрутизатора». Я думаю, что более полезным будет обсуждение: «Как я могу постепенно перенести огромное приложение с помощью response-router на Next.js?»

Маршрутизатор Next не имеет возможности вкладывать просмотры маршрутов, не так ли? Каждая навигация по маршруту уничтожает DOM и обновляет его. Вложенные представления - довольно распространенное требование.

@dbbk Я слышал, что над этим работает команда nextjs.

next js довольно гибок с маршрутизаторами. https://dev.to/toomuchdesign/next-js-react-router-2kl8

Я перемещаю веб-сайт с обычных кодов JS и jQuery на React. В отличие от старых кодов, мне нужно, чтобы музыка не останавливалась при смене страницы, поэтому я использовал для этого React Router.

Теперь для целей SEO, поскольку у меня есть хороший трафик из Google Search, мне нужно его поддерживать. Поэтому я бы предпочел SSR с Next.js для лучшей производительности.

Is Next.js может отображать страницу на стороне сервера, а затем, как только страница загружается на стороне клиента, Next.js разрешает навигацию под управлением React Router, так что если пользователь слушает музыку, ссылка Next.js выиграла ' разве нужно покинуть текущую страницу, чтобы остановить музыку?

Может Next.js выполняет только маршрутизацию на стороне клиента?

Если интеграция с React Router сможет решить эту проблему, значит, я в деле. Поскольку непрерывное воспроизведение музыки является для меня обязательным, когда приложение достигает клиентской стороны.

next js довольно гибок с маршрутизаторами. https://dev.to/toomuchdesign/next-js-react-router-2kl8

@laurencefass , это очень хороший подход, я читал его раньше. И в статье говорится, что команда Next.js не рекомендует его, не знаю почему. Но мне это кажется хорошо

@KeitelDOG, для этого вам не нужен реактивный маршрутизатор, маршрутизация Next.js принесет вам те же преимущества, плюс ваше приложение будет легче благодаря автоматическому разделению кода (что нелегко сделать с реактивным маршрутизатором)

_edit: я просто добавлю следующее: возможно, единственным преимуществом response-router являются простые вложенные маршруты в одной функции просмотра, маршрутизатор Next.js должен решить 95% ваших сценариев использования_

@martpie Спасибо за ответ, это то, что я видел вчера вечером с компонентом Link . Тогда Next.js - это смесь Сервер-Клиент, которую я хотел.

А для компонента, контролирующего свои собственные вложенные маршруты динамически, мне очень нравится React Router. Но я почти уверен, что смогу обойтись, потому что я не меняю веб-сайт React на Next.js, а вместо этого планирую и тестирую, чтобы изменить веб-сайт JS - jQuery на многостраничное приложение React без потери моих преимуществ SEO. в Google. Так что я думаю, мне стоит пойти с Next.js

@timneutkens есть ли планы поддержать это в Next.js 10?

@TrejGun, спасибо, это определенно не не по теме.

Есть план?
next/router великолепен, он очень помогает. Но нам нужен более профессиональный маршрутизатор, чтобы справляться со сложными приложениями. React-router - лидер среди роутеров.
Может быть, можно сослаться на after.js .

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

React-router собирается выпустить версию v6 , которая станет лучшим роутером на сегодняшний день. Я с нетерпением жду, когда next.js поддержат его.

Лучше всего разделить next.js и router , чтобы люди могли свободно выбирать свои любимые router .

+1 за предыдущий комментарий. next.js потрясающий, единственная причина, по которой я его не использую, - это отсутствие гибкости на маршрутизаторе. Пожалуйста, поддержите React Router 6 в будущих выпусках или сделайте роутер заменяемым.

Людям, действительно увлеченным React Router, возможно, будет интересно следить за новым проектом Remix, альтернативой Next.js, использующей React Router, от тех же создателей:

Я думаю, проблема в том, что фреймворк глубоко привязан к этому маршрутизатору из-за SSR, Server Side Props и т. Д.

Next построен с учетом производительности, а серверный реактивный маршрутизатор имеет большое значение для производительности, поскольку вы должны пройти по дереву DOM, прежде чем вы узнаете, что вы попытаетесь отобразить, и, следовательно, какие данные вам понадобятся. Вся цель getInitialProps состоит в том, чтобы вам не приходилось выполнять одноразовую визуализацию реакции перед извлечением данных - распространенная ошибка, с которой сталкиваются многие фреймворки на сервере (и на клиенте, где это проявляется как запрос водопадов). Затем потенциально можно обойти это, если каждая страница верхнего уровня объявляет _все_ различные шаблоны данных, которые могут понадобиться различным подкомпонентам, и разветвляется по полному пути запроса (или выполняет массивную однократную выборку с избыточной выборкой), но это быстро станет громоздким и на самом деле не будет так сильно отличаться от объявления каждой страницы по отдельности.

По этой же причине Relay несовместим с реактивным маршрутизатором, и вы не можете обвинить facebook.com в том, что он не является сложным веб-сайтом.

Основная успешная стратегия работы с маршрутизатором Next - это возможность компоновки (которая в любом случае является движущей силой современного React), позволяющая повторно использовать компоненты без значительного дублирования, а также иметь эффективный SSR, который может извлекать все свои данные. (через getInitialProps ), прежде чем разговаривать с рендерером React.

Мне кажется, что производительность ходьбы по дереву преувеличена. Многие производственные приложения сегодня делают это с помощью, например, Apollo, и, похоже, это нормально.

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

Конечно, я просто указываю на основную причину, по которой response-router (AFAICT) принципиально несовместим с Next в его текущей реализации. Многие сайты на самом деле вообще не нуждаются в производительности, о чем свидетельствуют люди, с удовольствием использующие бесплатные динамометрические устройства Heroku с медленным холодным запуском (и я хочу подчеркнуть, что я не говорю это снисходительно, поскольку я делаю это и для некоторых сайтов, и это может идеально подойти). Но Next не был бы популярен среди некоторых крупных компаний, использующих его, если бы он был менее агрессивен в отношении производительности, поскольку эти компании заботились бы о том, чтобы время отклика их серверов было заметно медленнее. Если бы это не было проблемой для некоторых сайтов, люди не использовали бы (и с нетерпением ждали бы улучшений) потоковый рендерер React, чтобы начать отвечать до того, как будет завершен хотя бы один рендеринг, не говоря уже о двух.

Вы определенно можете кэшировать свои ответы в CDN, но это устраняет множество вариантов персонализации / входа в систему (поскольку это компромисс между тем, насколько низко вы хотите снизить частоту посещений или отложить частичную отрисовку страницы для клиента). Если вы можете CDN кэшировать все свое приложение, возможно, вам лучше использовать CRA и react-snapshot и полностью избегать серверов. Вопрос не обязательно в том, сколько работы выполняет ваш сервер, а скорее в том, сколько времени требуется, чтобы ответить на запрос.

И Apollo - отличный пример фреймворка, который делает упор на простоту использования, а не на производительность, по сравнению с более самоуверенным / ориентированным на производительность фреймворком, таким как Relay. Это все спектр.

Да, думаю, это справедливо. Но мне любопытно посмотреть, как получится remix.run, может быть, они придумают новый подход, чтобы заставить его работать с react-router . Да, это правда, что вложенные маршруты не являются обязательными, но, конечно, вы должны согласиться с тем, что более интуитивно понятно, что части внутреннего пользовательского интерфейса изменяются вместе с маршрутом, чем иметь разные страницы и заключать каждую из этих страниц в разные макеты.

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

@merryweather : «Next построен с учетом производительности, а серверный

Наивный вопрос: можете ли вы просто отображать ссылки верхнего уровня и получать / предварительно получать / кешировать код, запущенный на клиенте. Если вы не знаете, куда будет перемещаться клиент, имеет ли смысл перемещаться по дереву DOM на сервере?

Наивный рабочий сценарий: когда клиент запрашивает URL-адрес, просто отображает ссылки верхнего уровня и активный контент ссылки по умолчанию, а ajax / fetch все остальное по запросу (или предварительная выборка в фоновом режиме после загрузки страницы) ... все остальное включает в себя все нижний уровень маршруты ... промыть и повторить ...?

@laurencefass, но даже ссылки верхнего уровня находятся в коде и должны быть обнаружены, верно? Или вы хотите использовать маршрутизацию файловой системы вместе с реактивным маршрутизатором, чтобы можно было обнаруживать ссылки верхнего уровня?

@ avin-kavish Я не лучший человек, чтобы ответить на подробности реализации, но на клиенте нужно только отобразить начальное содержимое экрана: ссылки верхнего уровня + содержимое по умолчанию. Я думаю, что все остальное избыточно при первой загрузке. Так зачем же ходить по DOM на сервере?

Основная проблема с Next.js - не в маршрутизаторе, а в шаблоне выборки данных с getInitialProps , getServerProps или getStaticProps . Почему ? Потому что это нарушает изоляцию данных для компонента, который в этом нуждается. Например, вы хотите получить данные для меню, откуда вы их получите? Я не знаю. Лучшие компоненты, такие как pages не должны ничего знать об этом, верно?

Основная проблема с Next.js - не в маршрутизаторе, а в шаблоне выборки данных с getInitialProps , getServerProps или getStaticProps . Почему ? Потому что это нарушает изоляцию данных для компонента, который в этом нуждается. Например, вы хотите получить данные для меню, откуда вы их получите? Я не знаю. Лучшие компоненты, такие как pages не должны ничего знать об этом, верно?

Не могли бы вы уточнить, пожалуйста. А какое альтернативное решение?

@lishine Мне очень жаль, что я здесь немного не по теме, но в большинстве случаев я не вижу, что маршрутизатор является основной проблемой. Маршрутизатор Next.js хороший, декларативный, соглашение по конфигурации - это хорошо. Единственное, что я не могу использовать в Next.js, - это такие методы выборки данных, как getInitialProps , ...
В моих приложениях каждый компонент должен будет объявлять свои собственные данные прямо в одном и том же месте, в том же файле, независимо от того, является ли это graphql или rest.
Компонент "Верхние страницы" предназначен только для создания дочерних компонентов, и получение данных не является его задачей. Дочерний компонент должен получать данные о себе, а не о своих родителях.

Вот мой образец кода, который я использую для своего приложения для ясности:

const query = `
{
  result:users(
    where:{
      _and:[{
        active:{
          _eq:true
        }
      }, {
        is_exam_manager:{
          _eq:true
        }
      }]
    },
    order_by:{
      created_at:desc_nulls_last
    }
  ){
    id
    key:id
    user_code
    first_name
    last_name
    password
    active
  }
}
`
const Main = (props: any) => {
  const {
    data: { result }
  } = props
  return (
    <div>
      <Add title={'Add user'} role={'exam_manager'} />
      <Table
        columns={columns}
        dataSource={result}
        bordered={true}
        size={'small'}
      />
    </div>
  )
}
const MainWithData = graphql(query)(Main)
export default MainWithData

Как видите, у вас есть один компонент со своими данными. Вы можете положить его куда угодно.

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

В моих приложениях каждый компонент должен будет объявлять свои собственные данные прямо в одном и том же месте, в том же файле, независимо от того, является ли это graphql или rest.
Компонент "Верхние страницы" предназначен только для создания дочерних компонентов, и получение данных не является его задачей. Дочерний компонент должен получать данные о себе, а не о своих родителях.

Я так же использую.
Итак, вы не используете получение SSR ...
Тогда как же люди на самом деле получают SSR с помощью Next.js ?!

@linshine мы должны загрузить все, что нам нужно, на уровне верхней страницы.

@lishine Мне очень жаль, что я здесь немного не по теме, но в большинстве случаев я не вижу, что маршрутизатор является основной проблемой. Маршрутизатор Next.js хороший, декларативный, соглашение по конфигурации - это хорошо. Единственное, что я не могу использовать в Next.js, - это такие методы выборки данных, как getInitialProps , ...
В моих приложениях каждый компонент должен будет объявлять свои собственные данные прямо в одном и том же месте, в том же файле, независимо от того, является ли это graphql или rest.
Компонент "Верхние страницы" предназначен только для создания дочерних компонентов, и получение данных не является его задачей. Дочерний компонент должен получать данные о себе, а не о своих родителях.

Вот мой образец кода, который я использую для своего приложения для ясности:

...

Как видите, у вас есть один компонент со своими данными. Вы можете положить его куда угодно.

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

@ revskill10 Почему вы не можете сделать так, чтобы дочерний элемент включил этот фрагмент в запрос верхнего уровня? Тем более, что вы создаете больше дочерних фрагментов, вы получаете идеальную изоляцию данных. Наличие родительского запроса с дочерним фрагментом ничем не отличается от того, что дочерний запрос объявлен в JSX, поэтому у вас такой же уровень связи, но избегайте водопадов запросов (к сожалению, в REST гораздо сложнее).

У нас есть приложение Relay-Next, и этот шаблон отлично работает с инкапсуляцией данных и многоразовой композицией, и мы легко используем getInitialProps .

@merrywhether Не говоря уже о much harder in REST , у вашего подхода есть проблема: вы не можете решить, какой fragments будет SSG / SSR или будет CSR.
В моем подходе это так же просто, как импортировать этот компонент с помощью { noSSR: true/false} .

Я считаю, что привязка к конкретной библиотеке маршрутизации поставщика, которая не разделяет базовую реализацию с какой-либо основной библиотекой маршрутизации, вызывает крайнюю озабоченность.

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

Я понимаю сложность использования API верхнего уровня на основе компонентов react-router / @reach/router в качестве основы для SSR. Но это не веская причина для того, чтобы базовая реализация была полностью настраиваемой. SSG Гэтсби имеет те же проблемы, что и Next.js, и наполовину похожую структуру маршрутизации на основе файлов; но, насколько я понимаю, Гэтсби использует @reach/router под капотом для обеспечения своей реализации маршрутизации вместо того, чтобы заново изобретать колесо или раскрывать API ссылок, который несовместим с API ссылок, используемым другими библиотеками.

@dantman, могу я спросить, что вы выбрали в качестве альтернативы Next.js. Предполагая, что вам нужен рендеринг на стороне сервера ... Я пробовал After.js, возможно, он может дать некоторые идеи / идеи о том, как реализовать в Next.js, если он не поддерживается zeit.

@dantman, могу я спросить, что вы выбрали в качестве альтернативы Next.js. Предполагая, что вам нужен рендеринг на стороне сервера ... Я пробовал After.js, возможно, он может дать некоторые идеи / идеи о том, как реализовать в Next.js, если он не поддерживается zeit.

Извините, у меня нет для вас полезного ответа. SSR не было жестким требованием, поэтому мы просто продолжали использовать CRA, с которой был построен прототип.

Я думал, что Next.js является многообещающим универсальным фреймворком, поскольку недавно он получил возможность сочетать страницы SSR / SSG / только для клиента и мог работать как изоморфное приложение или как статическое приложение / приложение PWA. Настройка WebPack была заманчивой, потому что CRA усложняла использование globalize-compiler. Сервер Next.js был нейтральным / положительным, потому что нам в любом случае нужен сервер API для моста GraphQL / REST. И вариант SSR / SSG был положительным, поскольку я создаю ядро, на котором будут основаны полдюжины приложений, и не исключено, что оно может оказаться полезным в будущем. Однако у меня также были некоторые проблемы с тем, как работает SSR Next.js, и эти положительные моменты не стоили проблем, вызванных маршрутизатором.

@dantman

Я считаю, что привязка к конкретной библиотеке маршрутизации поставщика, которая не разделяет базовую реализацию с какой-либо основной библиотекой маршрутизации, вызывает крайнюю озабоченность.

Довольно странно квалифицировать компонент с открытым исходным кодом с API, который не изменился за 3 года из-за его высокой стабильности и «соответствие продукта / рынка» как «привязанный».

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

Как многие видели, как я комментирую в Твиттере, когда-то мы серьезно занимались слиянием в каком-то маршрутизаторе (хотя я не понимаю, какой из них является стандартом, по вашему мнению, Reach или React Router, и в какой основной версии). Но мир потянул нас по другим интересным направлениям. На самом деле мы даже не знали, зачем его добавлять, потому что каждый продолжал добиваться успеха с Next.js и создавать замечательные продукты.

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

Когда я говорю, что Next преуспел благодаря маршрутизатору, это потому, что он устранил две проблемы:
1️⃣ Идея выбора роутера . Если оглянуться назад, то удаление этого является отличным решением. За все время существования Next.js со стабильным маршрутизатором мир маршрутизаторов разделился и запустил всевозможные изменения API.

2️⃣ Кривая обучения роутера . Было проведено множество семинаров и учебных пособий по маршрутизации, но маршрутизация Next.js сначала занимает 2 секунды и дает вам платформу для создания невероятных вещей, и вы сразу переходите к разработке продукта.

Я хочу подчеркнуть этот последний момент. Рассмотрим один из самых новых и быстрорастущих веб-сайтов в мире, TikTok.com, созданный на Next.js. Всю топологию маршрутизации этого веб-сайта можно объяснить с помощью этой двухсекундной кривой обучения. https://www.tiktok.com/@sheezus.christ/video/6824007862197439750 - это pages/[user]/video/[id].js а https://www.tiktok.com/trending - pages/trending.js

Многие из последних нововведений Next.js, которые вам нравятся, такие как гибридный статический / SSG / SSR, также включены в наш дизайн маршрутизатора. Фактически, маршрутизатор также позволит реализовать множество других подобных оптимизаций, которые появятся в будущем для доставки меньшего количества JS клиентам.

Однако у меня также были некоторые проблемы с тем, как работает SSR Next.js, и эти положительные моменты не стоили проблем, вызванных маршрутизатором.

Хотел бы услышать об этом. В приведенном выше примере используется гибридный статический / SSR Next.js, и мы видим большой успех с его помощью по всем направлениям!

Это такая забавная ветка. У Next есть конкретные причины избегать каскадной маршрутизации (также известной как response-router и его друзья), поскольку getInitialProps позволяет много оптимизировать производительность, а подход Next оказывается довольно популярным, особенно потому, что некоторые люди специально хотят этих оптимизаций. Производительность требует компромиссов в дизайне, и иногда вы можете предпочесть дизайн производительности, но это не делает инструмент неправильным, а просто не подходит для конкретного проекта.

В конечном итоге, реагирующий маршрутизатор - это не все решения маршрутизации. У него есть свои плюсы и минусы, как и у Next. FWIW, Facebook не использует реагирующий маршрутизатор, и они, вероятно, кое-что знают об использовании React. Так что иметь альтернативы - это нормально, и на самом деле это одна из замечательных особенностей экосистемы JS: позволить разным вещам соревноваться на арене идей, и в конечном итоге мы все будем двигаться вперед.

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

В идеале они должны быть ориентированы на продукт («Мне нужно сделать X, но это невозможно» или «Y возможно, но не эргономично»). Мы всегда находимся в поиске улучшений, которые помогут вам сделать веб-сайты и приложения удобными для пользователей 🤗

@rauchg Можете ли вы объяснить причину наличия двух реквизитов, href и as для ссылки? Почему он не может сделать вывод о целевой странице на основе значения опоры as ?

Например, в экспрессе, если у меня есть маршрут как /blog/:slug , я могу просто отправить http-запрос на /blog/hello-world и ожидать, что маршрутизатор направит к нему. Мне не нужно отправлять на сервер одновременно /blog/:slug и blog/hello-world .

@ avin-kavish, это отличный вопрос. Необходимо провести важное различие между тем, что отображает URL, и тем, какая страница должна быть загружена. На самом деле TikTok использует это для рендеринга определенных вещей в модальных окнах, которые при обновлении страницы становятся другими страницами. Тем не менее, одно большое улучшение здесь состоит в том, что нам, возможно, следует статически обеспечить, чтобы вы ссылались на действительную страницу, которая существует в файловой системе. Мы продолжим обсуждение этого вопроса и отметим вас!

Я думаю, что для этого уже существует проблема https://github.com/zeit/next.js/issues/8207

В случае, если кто-то наблюдал за этой проблемой для реагирующего маршрутизатора, такого как функция «вложенных маршрутов», которая позволяет переходить на новые страницы без повторного рендеринга всего, как я, на самом деле есть специальная проблема, за которую вы можете наблюдать и голосовать. Я только что узнал об этом: https://github.com/zeit/next.js/issues/8193

@rauchg

Для того, чтобы быть ясно , в этом моем основном вопросе не является отсутствием компонента API RR / длинен стилем, я в порядке с SSR , способным файлом / конфигурация на основе API. Хотя я немного оптимистичен, что в будущем Suspense может сделать альтернативные SSR / API маршрутизации жизнеспособными. Моя основная проблема заключается в том, что маршрутизатор полностью настраивается, и любые общие проблемы в реализации реализуются повторно, а не передаются какой-либо части более широкого сообщества React.

Я считаю подход Гэтсби приемлемым. У них есть API маршрутизации на основе файлов и конфигурации на основе SSG, и они экспортируют свой собственный улучшенный компонент Link; но они используют @reach/router для обеспечения базовой реализации.

Я считаю, что привязка к конкретной библиотеке маршрутизации поставщика, которая не разделяет базовую реализацию с какой-либо основной библиотекой маршрутизации, вызывает крайнюю озабоченность.

Довольно странно квалифицировать компонент с открытым исходным кодом с API, который не изменился за 3 года из-за его высокой стабильности и «соответствие продукта / рынка» как «привязанный».

Маршрутизатор внутренне привязан к Next.js. Использование Next.js по одной причине означает привязку к маршрутизатору. Если мы примем Next.js и позже обнаружим, что next / router имеет ограничение, которое оказывается парализующим для чего-то, что мы пытаемся сделать, не будет абсолютно никакого разумного выхода. "Запирание" - прекрасный дескриптор для этого.

Сама по себе блокировка не будет большой проблемой. Использование Гэтсби @reach/router также будет заблокировано. Но @reach/router используется не только в Гэтсби. Мне не нужно доверять только сообществу Гэтсби в обслуживании всего стека маршрутизаторов; Я могу верить, что на него полагается более широкое сообщество и что в него вовлечено больше заинтересованных сторон (специфичных для стека маршрутизации), которые обеспечивают его обслуживание, справляются со сложными проблемами маршрутизации (например, доступностью) и зависят от более широкого и разнообразного сообщества, скорее всего, поделится любыми потенциально опасными проблемами, с которыми мы можем столкнуться в будущем.

хотя я не понимаю, какой из них является стандартом, по вашему мнению, Reach или React Router, и в какой основной версии

С точки зрения фактического стандарта того, как должен выглядеть <Link> . И Reach, и React Router (RR) имеют очень похожие API. например, <Link to='/about'>About</Link> действителен как в RR, так и в Reach (и, конечно, в расширении Gatsby). Что делает идиосинкразию Next.js <Link href='/about'><a>About</a></Link> намного более раздражающей.

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

На практике, хотя это относительно спорный вопрос. На данный момент я не видел ни одного маршрутизатора React, кроме RR и Reach с большой базой пользователей. И RR и Reach станут одной библиотекой, поэтому, какой бы вы ни начали, конечный результат будет одинаковым.

Некоторое время назад я пробовал Next, но отсутствие гибкости на маршрутизаторе привело меня к обнаружению реализации Razzle под названием After.js https://github.com/jaredpalmer/after.js?utm_source=hashnode.com.

Поскольку React Router - это просто пакет, можем ли мы не импортировать его и ограничить рендеринг только на стороне клиента, чтобы он работал как SPA там, где это необходимо, и давал нам маршруты вложенных компонентов? Разве маршрутизатор React не является просто набором компонентов, которые (потенциально) будут встроены в страницы и загружены с помощью маршрутизатора страниц Next.js, как и любые другие компоненты?

Я читал в предыдущих обсуждениях, что zeit планирует интегрировать RR, это все еще верно сегодня?

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

Добавляю свой голос по этому вопросу.

Еще один не упомянутый плюс заключается в том, что RR более тестируемый (на самом деле, нет официального API nextjs для тестирования маршрутизатора), он имеет MemoryRouter для упаковки тестов и историй.

Next.js имеет множество хороших функций (автоматический WebPack, статические файлы и TypeScript, например CRA, но не только для PWA; маршруты API; бессерверная поддержка, быстрое обновление и даже экспериментальная поддержка Expo для веб-приложений и нативных приложений) и ядро для SSR и SSG, даже если API для него не очень хорош. Но пока встроенная система маршрутизации и SSR / SSG у некоторых работает; для других они затрудняют разработку, потому что пределы обоих API предлагают неправильные компромиссы для указанного проекта.

Как насчет компромисса. В Next.js уже есть плагины. Вместо внутренней замены маршрутизатора, что, если бы мы отделили маршрутизатор и SSR API (т.е. getStaticProps / getServerSideProps в файлах маршрутов) от ядра Next.js. например, мы могли бы поместить самые фундаментальные части ядра в @next/core и переместить текущий самоуверенный маршрутизатор и get*Props API в @next/router . Для простоты и обратной совместимости next может быть фреймворком, который реэкспортирует @next/core и поставляется с предварительно настроенным маршрутизатором Vercel. Но тогда сообщество может разработать маршрутизаторы и SSR / SSG API с различными компромиссами, которые лучше подходят для проектов, которые в противном случае застряли бы, выбрасывая хорошие части Next.js с водой.

Некоторые мысли о том, что ядро ​​Next.js потребует от плагина маршрутизатора:

  • Учитывая запрос {url, body и т.д.}, ядро ​​будет ожидать, что плагин маршрутизатора отобразит этот запрос в документ (строковый или потоковый) или выдаст ответ (например, 404 или перенаправление).
  • При экспорте ядро ​​ожидает, что плагин маршрутизатора предоставит список страниц, которые необходимо отобразить.

@next/router , вероятно, реализует те же шаблоны через api, выполнив следующие действия:

  • По запросу, определение ответственного файла маршрута и нормальный рендеринг
  • На клиенте делает что-то похожее на то, что он в настоящее время делает, чтобы знать, когда вызывать API SSR и отображать нужный маршрут (возможно, перемещение API SSR на основе API на нормальный маршрут API)
  • При экспорте с использованием дерева файлов страниц и getStaticPaths для предоставления списка статических страниц

Я, вероятно, мог бы увидеть, как я экспериментирую с плагином маршрутизатора с использованием React Router v6 с @apollo/react-ssr и Suspense с react-ssr-prepass или react@experimental . Что исключает маршруты только SSR для изоморфных маршрутов SSR и реализует SSR / SSG без ограничения API стиля get*Props .

Я понял, что вложенная маршрутизация + SSG достижима без нарушения текущего API. Итак, у нас есть getStaticPaths на данный момент, мы можем использовать это, чтобы намекать на вложенные маршруты для предварительного рендеринга. Например,

Учитывая маршрут /foo/[...slug] ,

function FooPage() {

  return (
      <Switch>
          <Route path="/foo/bar">
              <SomeResource />
              <Route path={`${parenthPath}/baz`} component={SomeSubResource} />
          </Route>
          .... more routes
      </Switch>
  )
}

можно предварительно обработать с помощью,

export async function getStaticPaths() {

  return {
    paths: [
      { slug: [ 'bar' ] },
      { slug: [ 'bar', 'baz' ] },
    ],
  }
}

В настоящий момент next.js похож на серверную среду с удобством создания страниц в React. Он не такой мощный, как react-router . Маршрутизация на основе каталогов может иметь место при создании сайтов, ориентированных на потребителя, таких как tiktok, как упоминалось ранее, но для сложных порталов приложений, управляемых данными, вложенная маршрутизация по-прежнему играет ключевую роль. Вот почему в первую очередь были созданы одностраничные приложения, они позволяют изменять части пользовательского интерфейса без необходимости заменять всю страницу. Это можно использовать для удобного моделирования отношений ресурс-подресурс. В нынешнем виде я могу использовать next.js если бы я создавал общедоступные страницы потребительского сайта, например, сайта электронной коммерции, но когда мне нужно создать частные области, такие как порталы администрирования, покупателя и продавца, я бы перейти на CRA.

@ avin-kavish главная проблема не в том, чтобы заставить его работать, а в том, чтобы сделать его оптимизированным: каждая страница в Next.js по умолчанию имеет свой собственный пакет и оптимизирована для скорости.

Если вы начнете добавлять много контента / суб-контента на одну страницу, как вы это делали, вы можете в конечном итоге получить довольно большой пакет (что само по себе не «ужасно», но вы должны просто знать о компромиссы). Возможно, вы сможете выполнить некоторую ручную оптимизацию с помощью next/dynamic think :)

@rauchg единственное измерение не в том, хороший или плохой следующий маршрутизатор. Еще одна очень важная вещь - это переход на next.js и обратно, а также поддержка сообщества, и https://github.com/vercel/next.js/issues/1632#issuecomment -633310614 это хорошо сказано. Next.js - хорошее решение для абстрагирования многих шаблонов, которые требуются высококачественному приложению SSR, и поэтому он является очень привлекательной целью миграции для многих веб-приложений. Проблема сейчас в том, что потребуется полное переписывание маршрутизации как для перехода на next.js, так и для выхода из него, если возникнет такая необходимость.

Подключаемая маршрутизация, предложенная ранее @dantman, решила бы эту проблему очень элегантно и не потребовала бы от кого-либо продавать свои принципы 😉

Проблема с реактивным маршрутизатором (и любым решением для вложенной маршрутизации) заключается в том, что он значительно усложняет статический анализ, поскольку соответствующие пути кода для любого конкретного URL-адреса недоступны без запуска (или моделирования) самого кода. Next - это больше, чем просто фреймворк «разместить пользовательский интерфейс на веб-странице», поэтому, например, они работали с командой Chrome над созданием более оптимизированных стратегий объединения.

Пользователи response-router привыкли использовать response-loadable напрямую, поскольку rr полностью делегирует эту ответственность конечным пользователям, но Next пытается абстрагироваться и автоматизировать это, что непросто. Предлагаемый подход с подключаемым маршрутизатором, вероятно, должен будет включать подключаемые модули маршрутизатора, предоставляющие инфраструктуре обширную информацию о времени сборки, чтобы получить тот же тип вывода, поскольку каждый маршрутизатор должен знать, как генерировать такую ​​информацию на основе своих собственных шаблонов.

Чисто предположение, но я полагаю, что многие вещи находятся в подвешенном состоянии, пока React завершает Suspense, поскольку создание этого шаблона первого класса в библиотеке сильно повлияет на все библиотеки маршрутизатора, а также даст конкретную основу для создания асинхронных / загружаемых комплекты шаблонов.

Вкратце / хорошее резюме ниже: не существует такой вещи, как «универсальное решение». У всего есть компромиссы. Каждое «преимущество» нынешнего подхода Next.js имеет свои недостатки. Какие преимущества / недостатки являются наиболее важными, для каждого проекта разные. Следовательно, рекомендация для архитектуры подключаемого маршрутизатора / ssg / ssr. Разным проектам нужны разные вещи, и сейчас Next.js работает только с проектами, приоритет которых совпадает с тем, как вещи жестко запрограммированы в Next.js.

Проблема с реактивным маршрутизатором (и любым решением для вложенной маршрутизации) заключается в том, что он значительно усложняет статический анализ, поскольку соответствующие пути кода для любого конкретного URL-адреса недоступны без запуска (или моделирования) самого кода.

Честно говоря, это имеет значение только в том случае, если вы используете SSG и имеете кучу нединамических маршрутов. Если все ваши маршруты SSG или только клиентские, это бесполезно. И если большинство ваших маршрутов являются динамическими, вам в любом случае необходимо явно объявить их, используя getStaticPaths . Это будет тот же объем работы, что и явное определение маршрутов в гипотетическом плагине Next.js, который просто использует необработанный реактивный маршрутизатор без изменений и просит вас явно определить статические маршруты.

Это несомненно преимущество, и некоторые команды захотят его. Однако это только одна подгруппа потенциальных пользователей Next.js. Есть и другие группы, которым могут потребоваться некоторые из преимуществ, которые предоставляет RR или другая библиотека маршрутизации, и необходимость явного объявления статических маршрутов является приемлемым компромиссом или не проблемой. Например, мои последние несколько проектов относились к типу приложений B2B / B2C, где 100% вещей находятся за страницей входа, и нет смысла статически отображать что-либо из этого. Next.js имеет некоторые преимущества перед CRA, которые сделали бы Next.js предпочтительным; Но такие вещи, как маршрутизатор, были большими тревогами, и мы просто продолжали использовать CRA. Эти проекты очень хорошо подошли бы для Next.js с raw-response-router.

Это также предполагает, что каждый, кто не хочет next/router хочет использовать JSX-форму response-router. Это не единственный тип альтернативы next/router .

Еще один тип маршрутизатора - это стиль Gatsby.js. Если в проекте по-прежнему используется структура страниц на основе файловой системы, но внутренняя часть реализована с помощью другой библиотеки маршрутизации, такой как response-router (Gatsby использует @reach/router внутри). Такой плагин маршрутизатора даст вам те же преимущества статического анализа. Но это также даст вам те преимущества, которые альтернативный маршрутизатор не имеет отношения к вложенной маршрутизации. например, учет потенциальных предпочтений для API маршрутов, лучшая обработка доступности, лучшая интеграция в экосистему вокруг этого маршрутизатора.

И, конечно, даже в экосистеме реактивного маршрутизатора форма JSX - не единственный способ использования реактивного маршрутизатора. Также есть response-router-config . Которая легко выполняет статический анализ, а также поддерживает вложенную маршрутизацию.

Пользователи response-router привыкли использовать response-loadable напрямую, поскольку rr полностью делегирует эту ответственность конечным пользователям, но Next пытается абстрагироваться и автоматизировать это, что непросто.

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

Это скорее побочное примечание, но мне действительно интересно узнать о потенциале плагина babel / webpack, который будет делать это автоматически для маршрутов.

Также react-loadable - это фактически не существующая библиотека (2 года с момента публикации, отчеты об ошибках не принимаются). Лично я предпочел бы вручную выполнять разделение кода с помощью @loadable/components чем использовать что-то автоматическое, встроенное в Next.js, основанное на внутренней вилке response-loadable.

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

Ага. Обычно так работает система плагинов. Честно говоря, тот факт, что такую ​​информацию может предоставлять плагин, является преимуществом, а не проблемой. Наличие этого в плагине означает, что если способ, которым Next.js собирает эту информацию, не подходит для нужд некоторых типов проектов, его можно заменить на тот, который соответствует потребностям этих проектов. Но без необходимости форкнуть и переписать все Next.js для этого.

Чисто предположение, но я полагаю, что многие вещи находятся в подвешенном состоянии, пока React завершает Suspense, поскольку создание этого шаблона первого класса в библиотеке сильно повлияет на все библиотеки маршрутизатора, а также даст конкретную основу для создания асинхронных / загружаемых комплекты шаблонов.

Это само по себе может быть довольно хорошим аргументом в пользу работы в системе подключаемого маршрутизатора. Прямо сейчас, поскольку вся маршрутизация и SSR жестко запрограммированы в Next.js, невозможно легко провести эксперименты с любым типом будущей системы маршрутизации в Next.js. Как Suspense влияет на маршрутизацию Next.js и другие библиотеки маршрутизации? Это не то, с чем вы можете экспериментировать (по крайней мере, в отношении SSR Next.js и объединения) без разветвления и перезаписи фрагментов Next.js.

Плагины маршрутизатора были бы отличным местом для экспериментов такого рода. Пока API плагина достаточно низкоуровневый, можно было бы форкнуть только плагин next/router и попробовать написать версию этого роутера, основанную на реакции @ экспериментальной + Suspense. А поскольку это плагин (а не форк всех Next.js), было бы легко принять участие в эксперименте и протестировать новый маршрутизатор на основе Suspense. Это очень важно сейчас , а не позже , потому что этот вид экспериментирования почему реагирует @ экспериментальные существует, чтобы собрать отзывы от реальных проектов.

@dantman Я не

Честно говоря, это имеет значение только в том случае, если вы используете SSG и имеете кучу нединамических маршрутов.

Я не уверен, что вы имеете в виду под этим, поскольку SSG против SSR на самом деле не имеет значения для попытки доставить минимально возможную полезную нагрузку JS для первой страницы (JS «критический путь»), как и динамические маршруты. Сведение к минимуму ресурсов критического пути _is_ обычно очень важно для приложений SSR (а значит, и все усилия), поэтому это приветствуется. И, честно говоря, если все, что вы делаете, - это приложения только для CSR с входом в систему, то Next _ имеет_ много недостатков по сравнению с CRA (SSR никогда не будет так удобен, как CSR). Похоже, вы обесцениваете те приложения, которые на самом деле выполняют SSR во время выполнения (с обработкой входа / персонализации на стороне сервера) специально для победы производительности. Не все укладывается в дихотомию SSG vs CSR.

некоторые из нас прекрасно справляются с разделением кода самостоятельно

Некоторые из нас сами вполне способны обрабатывать webpack, react-dom / server и т. Д. Пока что цель Next заключалась в том, чтобы сделать такие выбросы более редкими, как и CRA. И вы правы, я должен был сказать, что реагирует на загрузку одинаково, потому что в этом пространстве есть множество решений, и они становятся только более экзотическими с появлением шаблонов данных плюс код из таких библиотек, как Relay.

В конечном счете, я не возражаю, что подключаемая система маршрутизатора может быть хорошей. Я просто указывал на то, что команде Next потребуется много работы, чтобы удалить вещи, которые являются центральными принципами фреймворка (например, логику разделения пакетов), и извлечь их в подключаемую архитектуру. И мои предположения подчеркивали тот факт, что я не хотел бы начинать разрабатывать фундаментальные изменения в моей библиотеке, которые могут быть легко отменены предстоящими изменениями в моей основной зависимости. Я, конечно, согласен с тем, что некоторые аспекты дизайна Next _ являются_ ограничениями, но по большей части эти ограничения имеют смысл, учитывая их ограничения дизайна до сих пор.

Честно говоря, это имеет значение только в том случае, если вы используете SSG и имеете кучу нединамических маршрутов.

Я не уверен, что вы имеете в виду под этим, поскольку SSG против SSR на самом деле не имеет значения для попытки доставить минимально возможную полезную нагрузку JS для первой страницы (JS «критический путь»), как и динамические маршруты.

Вероятно, мы думаем о разных причинах, по которым необходима возможность статического анализа существующих маршрутов. Предполагая, что мы оба говорим о «статическом анализе» как о «способности идентифицировать список маршрутов (например, ['/about', '/', '/profile'] ) во время сборки просто путем чтения кода».

Похоже, вы говорите о какой-то оптимизации пакетов JS? Я не нашел никакой информации в документации, поэтому я не знаю, какой именно тип оптимизации на основе статического анализа маршрута вы думаете.

Я думал, что этот статический анализ маршрутов был в первую очередь полезен для SSG. т.е. поскольку файл pages/about.js существует, когда вы создаете свой сайт, Next.js знает, что существует маршрут /about и ему необходимо предварительно отобразить html для этого маршрута, даже если вы никогда явно не говорили об этом есть маршрут /about для предварительного рендеринга.

SSR не нуждается в предварительно созданном html, поскольку он делает это только при поступлении запроса (в этот момент он запускает код и имеет один путь для рендеринга). Страницы, отображаемые клиентом, вообще не имеют предварительно обработанного HTML. И если ваша страница SSG динамическая, вам в любом случае нужно объявить все пути. Отсюда мои мысли.

И, честно говоря, если все, что вы делаете, - это приложения только для CSR с входом в систему, то Next _ имеет_ много недостатков по сравнению с CRA (SSR никогда не будет так удобен, как CSR).

Какие недостатки вы думаете в Next.js в отношении приложений CSR? Помимо вышеупомянутых проблем с маршрутизатором.

Насколько я понимаю, Next.js поддерживает весь спектр маршрутов SSR / SSG / CSR. Таким образом, он, предположительно, все еще подходит для написания приложений CSR только для входа в систему.

Лично моя точка зрения определенно исходит из того, что кто-то пишет множество приложений, в основном CSR, время от времени требуя SSR и SSG, желая иметь единый надежный инструментарий для всех моих проектов, независимо от того, какое сочетание SSR / SSG / CSR им нужно.

По моему опыту, CRA имеет ряд недостатков даже в приложениях, предназначенных только для CSR, которые могут сделать CSR-страницы Next.js более выгодными. Настройка конфигурации WebPack без извлечения - большая проблема. Это причиняло мне много боли, когда я не мог просто использовать плагин globalize-compiler WebPack, когда добавлял i18n в приложение. Возможность выбрать SSR / SSG для определенных страниц, даже если большинство страниц являются CSR, также является преимуществом (например, 99,9% ваших страниц являются CSR и находятся за страницей входа; но у вас есть целевая страница и, возможно, условия / контакт страницы, на которых вы хотите включить SSG или SSR). Ничего из этого невозможно сделать с такими вещами, как CRA.

некоторые из нас прекрасно справляются с разделением кода самостоятельно

Некоторые из нас сами вполне способны обрабатывать webpack, react-dom / server и т. Д. Пока что цель Next заключалась в том, чтобы сделать такие выбросы более редкими, как и CRA.

Честно говоря, ручное разделение кода на основе маршрута (убедитесь, что вы изменили его для использования компонентов маршрута через React.lazy или альтернативную библиотеку вместо прямого импорта) - это очень далеко от ручного управления настраиваемой конфигурацией WebPack или написания ваши собственные обработчики SSR с react-dom/server .

Совершенно разумно не захотеть вручную писать всю конфигурацию WebPack или настраиваемый SSR-сервер (т.е. хотеть использовать широко используемый фреймворк, такой как Next.js), но все равно будет в порядке с использованием response-router и ручным выполнением кода на основе маршрута - расщепление. Особенно, если выбор автоматического разделения базового кода маршрута означает потерю широко используемой библиотеки маршрутизатора, которую вы используете, и использование маршрутизатора, в котором отсутствует ряд функций, которые могут вам понадобиться с API, сильно отличающимся от любого из маршрутизаторов, которые используются более широко.

Я всегда сталкиваюсь с этой проблемой при поиске способа интеграции react-router с NextJS, который не требует создания настраиваемого сервера, поэтому я решил попробовать сам.

С помощью react-router v6 (бета) создайте собственный _app :

// _app.js || _app.tsx
import * as React from 'react'
import App from 'next/app'
import NextRouter from 'next/router'

export default class CustomApp extends App {
    render() {
        const { Component, pageProps } = this.props

        if (process.browser) {
            const { Router } = require('react-router-dom')
            const { createMemoryHistory } = require('history')
            const history = createMemoryHistory({
                initialEntries: [this.props.router.asPath],
            })

            history.listen(function ({ action, location }) {
                const url = {
                    hash: location.hash,
                    pathname: location.pathname,
                    search: location.search,
                }
                switch (action) {
                    case 'PUSH':
                        return NextRouter.push(url)
                    case 'REPLACE':
                        return NextRouter.replace(url)
                    default:
                        return void 0
                }
            })

            return (
                <Router location={history.location} navigator={history} action={history.action}>
                    <Component {...pageProps} />
                </Router>
            )
        } else {
            const { StaticRouter } = require('react-router-dom/server')
            return (
                <StaticRouter location={this.props.router.asPath}>
                    <Component {...pageProps} />
                </StaticRouter>
            )
        }
    }
}

Почему

Управлять _optional catch all routes_ в NextJS непросто (например: /foo/[[...bar]].js ), поэтому я ищу способ использовать react-router для страниц такого типа. Возможно, у других есть другие причины, но это моя основная проблема, и react-router предоставляет хороший API, особенно в версии 6, которая в настоящее время находится в стадии бета-тестирования.

Как это устроено

Он просто создает пользовательский MemoryRouter вместо BrowserRouter чтобы мы не испортили историю браузера, имея маршрутизатор NextJS и маршрутизатор NextJS. Он прослушивает изменения истории памяти для PUSH и REPLACE поэтому вы можете использовать react-router hooks или Link для навигации, но под капотом это будет вызов методов маршрутизатора NextJS .push и .replace .

Вызов методов маршрутизатора NextJS необходим, иначе изменения маршрута не будут запускать методы NextJS get*Props . Другими словами, он будет работать так же, как опция shallow используя NextJS Link . Обратной стороной использования react-router Link является отсутствие prefetch . Однако вы все равно можете использовать NextJS Link а react-router прежнему может реагировать на изменения маршрута.

Самое замечательное в этом то, что теперь вы можете использовать маршруты NextJS dynamic и react-router и делать такие вещи, как:

// /foo/[[...bar]].js
import * as React from 'react'
import { Route, Routes } from 'react-router-dom'
import dynamic from 'next/dynamic'

const Home = dynamic(() => import('src/views/Home'))
const About = dynamic(() => import('src/views/About'))
const Navigation = dynamic(() => import('src/views/Navigation'))

export default function Root() {
    return (
        <>
            <Navigation />
            <Routes>
                <Route path="/foo/" element={<Home />} />
                <Route path="/foo/about" element={<About />} />
            </Routes>
        </>
    )
}

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

Использование React Router с Next.js 9.5+

Если вы используете Next.js 9.5 или новее, правильный способ сделать это - перезаписать . _Не используйте собственный сервер_! Подробное руководство о том, как это сделать, можно найти здесь: https://colinhacks.com/essays/building-a-spa-with-nextjs

Основная мысль:

  1. Создать собственное приложение ( /pages/_app.tsx )

  2. Вернуть null если typeof window === "undefined" . Это необходимо для предотвращения появления ошибок реактивного маршрутизатора на этапе SSR!

// pages/_app.tsx

import { AppProps } from 'next/app';

function App({ Component, pageProps }: AppProps) {
  return (
    <div suppressHydrationWarning>
      {typeof window === 'undefined' ? null : <Component {...pageProps} />}
    </div>
  );
}

export default App;

Атрибут suppressHydrationWarning предназначен для предотвращения предупреждений, которые React выдает, когда контент, отображаемый на сервере, не согласуется с содержимым, отображаемым клиентом.

  1. Перепишите все маршруты на главную
// next.config.js

module.exports = {
  async rewrites() {
    return [
      // Rewrite everything else to use `pages/index`
      {
        source: '/:path*',
        destination: '/',
      },
    ];
  },
};

Тогда вы можете использовать React Router как обычно! В связанном руководстве гораздо больше контекста / объяснений, но это поможет вам начать. https://vriad.com/essays/building-a-spa-with-nextjs

@colinhacks Хорошее решение может подтвердить, что оно работает. Возможно, стоит подумать о переносе приложения на отдельную страницу, например app.js или routes.js или что-то в этом роде. Затем переписывает на

// next.config.js

module.exports = {
  async rewrites() {
    return [
      {
        source: '/app/:path*',
        destination: '/app',
      },
    ];
  },
};

Просто подумайте, ваше решение - лучшее, что я нашел.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги