React route не работает с путями, отличными от "/", используя webpack - PullRequest
0 голосов
/ 11 января 2020

Проблема

Я пытаюсь маршрутизировать на /song/new, но получаю следующее сообщение (без дополнительной ошибки в консоли):

Cannot GET /song/new

Путь root / работает.

То, что я пытался

  • , используя точное на root пути
  • добавление к webpack.config. js publicPath (в devserver и output) и historyApiFallback: true,
  • обновление версии имеющихся у меня пакетов
  • с добавлением <base href="/" /> к index. html

Вот код.

зависимости

"dependencies": {
"@apollo/client": "^3.0.0-beta.20",
"@apollo/react-hoc": "^3.1.3",
"@babel/core": "^7.7.7",
"@babel/preset-env": "^7.7.7",
"@babel/preset-react": "^7.7.4",
"apollo-client": "^2.6.8",
"axios": "^0.19.1",
"babel-loader": "^8.0.6",
"body-parser": "^1.16.0",
"connect-mongo": "^1.3.2",
"css-loader": "^3.4.2",
"express": "^4.14.0",
"express-graphql": "^0.6.1",
"express-session": "^1.15.0",
"graphql": "^0.8.2",
"html-webpack-plugin": "^3.2.0",
"lodash": "^4.17.4",
"mongoose": "^5.8.7",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"react": "^16.12.0",
"react-apollo": "^3.1.3",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"style-loader": "^0.13.1",
"webpack": "^4.41.5",
"webpack-dev-middleware": "^3.7.2"

клиент / индекс. html

<head>
  <link rel="stylesheet" 
   href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css">
  <link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
   <base href="/" />
 </head>
 <body>
  <div id="root"></div>
</body>

клиент / индекс. js

const Root = () => {
return (
 <ApolloProvider client={client}>
   <Router>
     <App/>
   </Router>
 </ApolloProvider>
 )
 };

Приложение. js

const App = () => {
return (
    <div className="container">
        <Switch>

            <Route exact path="/">
                <SongList />
            </Route>

            <Route path="song/new">
                <SongCreate />
            </Route>

        </Switch>
    </div>
)
}

webpack.config. js

module.exports = {
 mode: 'development',
 entry: './client/index.js',
 output: {
   filename: 'bundle.js',
 },
 module: {
   rules: [
     {
       use: [{
         loader: 'babel-loader',
         options: {
           presets: [
            ['@babel/preset-env']
           ]
         }
       }],
       test: /\.js$/,
      exclude: /node_modules/
    },
    {
      test: /\.css$/,
      use: [
         "style-loader",
       {
          loader: "css-loader",
        }
      ]
    }
   ]
 },
 devServer: {
   publicPath: '/',
   historyApiFallback: true,
},
 plugins: [
  new HtmlWebpackPlugin({
    template: 'client/index.html'
  })
 ]
};

И это был веб-пакет, выполненный :

сервер. js

const webpackMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('../webpack.config.js');
app.use(webpackMiddleware(webpack(webpackConfig)));

Ответы [ 2 ]

0 голосов
/ 31 марта 2020

Работа с последней версией response-router и response-router-dom (5.1.2) по состоянию на март 2020 года.

Cannot GET /song/new

Вы получаете эту ошибку, потому что:

  1. Внутренний сервер не настроен на перенаправление неизвестных запросов GET в React.

  2. Вы используете маршрутизатор (это маршрутизатор низкого уровня, Вы должны использовать маршрутизатор высокого уровня).

Решение состоит в том, чтобы использовать <HashRouter /> или <MemoryRouter />, , а не <Router /> или <BrowserRouter />


HashRouter добавит га sh в ваш маршрут.

Пример: http://localhost:4000/#/

Все, кроме #, игнорируется современными браузерами, и на самом деле ни один запрос не выполняется переданный означает, что Node / Express никогда не получит запрос, что в конечном итоге означает, что React может перемещаться самостоятельно, без необходимости конфигурировать бэкэнд с промежуточным программным обеспечением.

BrowserRouter можно рассматривать как нормальную маршрутизацию.

Пример: http://localhost:4000/users/new

Это действительный URL-адрес, и запрос будет обработан Express. Если бэкэнд не настроен для работы с React, у вас наверняка возникнут проблемы.

Реализация:

// Make sure this is imported from react-router-dom NOT react-router!!!

import {HashRouter, Route, Switch} from 'react-router-dom';

ReactDOM.render(
    <ApolloProvider client={client}>
        <HashRouter>
            <Switch>
                <Route path="/" component={App} exact/>
                ....define more routes here!!
            </Switch>
        </HashRouter>
    </ApolloProvider>,
    document.querySelector('#root')
);

Обратите внимание, что нам не нужен импорт hashHistory и нам не нужен IndexRoute. Если вы хотите sh перенаправить пользователей через прослушиватели событий, используйте объект истории на подпорках (предоставленных нам React Router):

this.props.history.push("/some/route/goes/here"); 
0 голосов
/ 12 января 2020

Попробуйте удалить publicPath. Это может быть ошибка с путем приложения.

...