Далее JS: как обрабатывать несколько динамических c маршрутов на root - PullRequest
1 голос
/ 17 января 2020

Цель: Я хотел бы добиться маршрутизации в стиле github, где abcd в github.com/abcd может разрешить переход на страницу профиля пользователя или страницу команды.

У меня сейчас есть версия, которая работает (см. Ниже). К сожалению, я иногда получаю белую страницу fla sh при переходе между двумя динамическими c маршрутами.

Файл моего сервера выглядит так:

const express = require('express');
const next = require('next');
const { parse } = require('url');
const resolveRoute = require('./resolveRoute');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({
  dev,
});
const nextHandle = nextApp.getRequestHandler();

const STATIC_ROUTES = [
  '/about',
  '/news',
  '/static',
];

const DYNAMIC_ROUTE_MAP = {
  user: '/[user]',
  team: '/teams/[team]',
};

nextApp.prepare().then(() => {
  const server = express();

  server.get('*', async (req, res) => {
    // pass through next routes
    if (req.url.indexOf('/_next') === 0) {
      return nextHandle(req, res);
    }

    // pass through static routes
    if (
      req.url === '/' ||
      STATIC_ROUTES.map(route => req.url.indexOf(route) === 0).reduce(
        (prev, curr) => prev || curr,
      )
    ) {
      return nextHandle(req, res);
    }

    // try to resolve the route
    // if successful resolves to an object:
    // { type: 'user' | 'team' }
    const resolvedRoute = await resolveRoute(req.url);
    if (!resolvedRoute || !resolvedRoute.type) {
      console.error('? Unable to resolve route...');
      return nextHandle(req, res);
    }

    // set query
    const { pathname } = parse(req.url);
    const paths = pathname.split('/').filter(path => path.length > 0);
    const query = {
      [resolvedRoute.type]: paths.length > 0 ? paths[0] : null,
    };

    // render route
    return nextApp.render(
      req,
      res,
      DYNAMIC_ROUTE_MAP[resolvedRoute.type],
      query,
    );
  });

  server.listen(port, err => {
    if (err) throw err;
    console.log(`? Ready on http://localhost:${port}`);
  });
});

Мне интересно, есть ли лучший способ справиться с этим или если мне нужно отойти от Next JS.

1 Ответ

4 голосов
/ 17 января 2020

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

Чтобы создать динамический c маршрут в Next. JS вы можете создавать страницы с именами, заключенными в квадратные скобки, например /pages/[username].js. Это будет соответствовать всем маршрутам в вашем базовом домене, поэтому вы можете настроить пример, который вы упомянули, с помощью github, например http://yourwebsite.com/csbarnes и http://yourwebsite.com/anotherusername.

В В приведенном выше примере вы можете получить имя пользователя на своей странице Next. JS из параметра запроса в getInitialProps точно так же, как вы это делаете с любыми параметрами строки запроса:

static getInitialProps({query}) {
  console.log(query.username); // the param name is the part in [] in your filename
  return {query}; // you can now access this as this.props.query in your page
}

Next. JS всегда соответствует stati c маршруты перед динамическими c маршруты означают, что ваша директория /pages/ может выглядеть следующим образом:

pages/index.js       -> (will match http://yourwebsite.com)
pages/about.js       -> (will match http://yourwebsite.com/about)
pages/contact.js     -> (will match http://yourwebsite.com/contact)
pages/[username].js  -> (will match http://yourwebsite.com/[anything_else])

Несколько сегментов

Вы можете иметь несколько сегментов Dynami c маршруты, например http://website.com/[username]/[repo] с использованием папок в каталоге pages:

pages/[username].js      -> (matches http://yourwebsite.com/[username])
pages/[username]/[repo]  -> (matches http://yourwebsite.com/[username]/[repo])

В этом случае ваш объект запроса будет содержать 2 параметра: { username: ..., repo: ...}.

Route "префиксы" "

Вы можете иметь несколько динамических c маршрутов с разными" префиксами ", если вы используете sh, создавая папки в каталоге pages. Вот пример структуры папок с маршрутом website.com/[username] и маршрутом website.com/teams/[team]:

multiple dynamic routes

Dynami c число различных сегментов

Вы также можете иметь динамические c маршруты с любым количеством динамических c сегментов. Для этого вам нужно использовать многоточие ("...") в имени файла маршрута Dynami c:

/pages/[...userDetails].js  -> (will match http://website.com/[username]/[repo]/[etc]/[etc]/[forever]) 

В этом случае переменная this.props.userDetails будет возвращать массив, а не строка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...