TypeError: _Router2.default.computeRootMatch не является функцией в конфигурации с реагирующим маршрутизатором - PullRequest
0 голосов
/ 09 октября 2018

Я выполняю рендеринг на стороне сервера для моего приложения React Js. Когда я запускаю свое приложение, я получаю нижеуказанную ошибку.

TypeError: _Router2.default.computeRootMatch не является функцией в/home/../web/node_modules/react-router-config/matchRoutes.js:20:24 в Array.some (нативный) в matchRoutes (/home../web/node_modules/react-router-config/matchRoutes).js: 18: 10) в /home/../web/build/bundle.js:2250:53 в Layer.handle [как handle_request] (/home/../web/node_modules/express/lib/router/layer.js: 95: 5) в следующем (/home/../web/node_modules/express/lib/router/route.js:137:13) в Route.dispatch (/home../web/node_modules/express/lib / router / route.js: 112: 3) в Layer.handle [как handle_request] (/home../web/node_modules/express/lib/router/layer.js:95:5) в /home../web / node_modules / express / lib / router / index.js: 281: 22 в параметре (/home/../web/node_modules/express/lib/router/index.js:354:14)

файл server.js

import express from 'express';
import { matchRoutes } from 'react-router-config';
import Routes from './client/Routes';
import renderer from './helpers/renderer';
import createStore from './helpers/createStore';
const app = express();

app.use(express.static('public'));
app.get('*', (req, res) => {
  const store = createStore(req);

  const promises = matchRoutes(Routes, req.path)
    .map(({ route }) => {
      return route.loadData ? route.loadData(store) : null;
    })
    .map(promise => {
      if (promise) {
        return new Promise((resolve, reject) => {
          promise.then(resolve).catch(resolve);
        });
      }
    });

  Promise.all(promises).then(() => {
    const context = {};
    const content = renderer(req, store, context);

    if (context.url) {
      return res.redirect(301, context.url);
    }
    if (context.notFound) {
      res.status(404);
    }

    res.send(content);
  });
});

app.listen(3000, () => {
  console.log('Listening on prot 3000');
});

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Я знаю, где это терпит неудачу, потому что я только что прошел этот же курс Удеми.Если вы обновляете response-router-config, вашему корневому узлу для вашего массива Routes требуется определенный путь.В: https://github.com/ReactTraining/react-router/issues/6381. Так что-то вроде:

export default [
  {
    ...App,
    path: '/',
    routes: [
      {
        ...HomePage,
        path: '/',
        exact: true
      },
      {
        ...AdminsListPage,
        path: '/admins'
      },
      {
        ...UsersListPage,
        path: '/users'
      },
      {
        ...NotFoundPage
      }
    ]
  }
];

должно сработать.

0 голосов
/ 12 октября 2018

У меня такой же вариант использования, и я не могу заставить его работать.Я использую веб-пакет.С веб-пакетом 3 этот код работает нормально:

renderer.js (работает с веб-пакетом 3)
import { h } from 'preact';
import render from 'preact-render-to-string';
import {routes, createHistory, makeStore, AppBar, NavBar} from '../dist/ssr-bundle'
import {renderRoutes, matchRoutes} from 'react-router-config';
import {ConnectedRouter} from 'connected-react-router';
import {Provider} from 'react-redux';
import {ServerStyleSheet} from 'styled-components';
import fs from 'fs';
import mapping from '../dist/assets-manifest.json';

const prerenderIndex = fs.readFileSync('./dist/index.html', 'utf8');
const html = prerenderIndex
  .replace(/\<style data-styled-components=".*\<\/style\>/g, 'ssrstyledcomponents')
  .replace(/\<body\>.*\<\/body\>/g, 'ssrcontent');

const loadRouteDependencies = (location, store) => {
  const dataRequirements = matchRoutes(routes, location)
      .filter(route => route.route.component && route.route.component.loadData) // filter components with loadData
      .map(route => route.route.component.loadData(store, route.match)); // dispatch data requirement
  return Promise.all(dataRequirements);
}

const loadRouteChunks = (location) => {
  const neededChunks =  matchRoutes(routes, location).map(route => route.route.name); // route.route.name defined with webpack4
  return neededChunks; //returns undefined with webpack4
}

export const handleRender = (req, res) => {
  const history = createHistory({initialEntries: [req.originalUrl]});
  const store = makeStore(history, req.originalUrl);

  const chunks = loadRouteChunks(req.originalUrl)
    .map(item => mapping[item])
    .map(item => `<script defer="defer" src="/${item}"></script>`)
    .join(' ');

  loadRouteDependencies(req.originalUrl, store).then(() => {
    const App = (
      <Provider store={store}>
        <div id="app">
          <ConnectedRouter history={history}>
            <div>
              <AppBar size={'large'}/>
                {renderRoutes(routes)}
              <NavBar/>
            </div>
          </ConnectedRouter>
        </div>
      </Provider>
    )

    const sheet = new ServerStyleSheet()
    const body = render(sheet.collectStyles(App));
    const redux = `<script>window.REDUX_DATA = ${JSON.stringify(store.getState())}</script>`;
    const doc = `<body>${body}<script></script>${redux}</body>`;
    const document = html
      .replace(/ssrstyledcomponents/, sheet.getStyleTags())
      .replace(/ssrcontent/, doc)
      .replace(/\<script\>\<\/script\>/, chunks);
    res.status(200).send(document);
  });
}

Поскольку я использую веб-пакет 4, код больше не работает и выдает ту же ошибку типа.Я не уверен, почему это происходит, потому что действительно странно то, что код, в котором matchRoutes вызывается только в loadRouteDependencies, работает без ошибок и ведет себя правильно.

server.js как выше, но без
const chunks = loadRouteChunks(req.originalUrl)
    .map(item => mapping[item])
    .map(item => `<script defer="defer" src="/${item}"></script>`)
    .join(' ');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...