反应客户端路由尝试发出服务器请求

时间:2020-03-30 16:02:41

标签: javascript reactjs express webpack react-router-dom

我有一个带有快速服务器的React应用。教程设置项目的方式是,在根端口5000上运行一个server.js的根文件夹,然后在React应用程序(带有它自己的package.json,webpack等)下创建一个客户端文件夹。 Webpack开发服务器在端口8080上运行。

folder structure

我遇到的麻烦是React应用在Webpack开发服务器上运行时没有进行客户端路由。我正在使用<Switch><Route>,并且我的初始归属路线正常。但是,在浏览器中键入任何其他选项都会失败。即使我使用react-router-dom的<Link>,该链接也可以正常工作,但是在刷新后,页面尝试执行服务器请求,但找不到指定的页面。构建好生产应用程序并将其在服务器上运行后,它可以正常工作,但是我不知道为什么它无法在webpack开发服务器上正确路由。

请注意,进入webpack开发服务器的入口位于根package.json中,使用“ npm run dev”运行,这将启动快速服务器,然后进入客户端文件夹并运行其“ npm run start”。

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter} from 'react-router-dom';
import configureStore from './redux/configureStore';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css';

const store = configureStore();

const app = (
    <Provider store={store}>
        <BrowserRouter>
            <App />
        </BrowserRouter>
    </Provider>
);

ReactDOM.render(app, document.getElementById('root'));

App.js

import React from 'react';
import { Route, Switch } from 'react-router-dom';
import Header from './components/header/Header';
import Main from './components/main/Main';
import PageNotFound from './components/page-not-found/PageNotFound';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';

function App() {
  return (
    <>
        <Header />
        <Switch>
          <Route exact path="/" component={Main} />
          <Route path="/h" component={Header} />
          <Route component={PageNotFound} />
        </Switch> 
    </>
  );
}

export default App;

server.js

const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');

const app = express(); 

//Bodyparser Middleware
app.use(bodyParser.json());

//Use routes
app.get('/health', function(req, res) {
    res.status(200).send({
      title: 'HealthCheck',
      message: 'Healthy health check',
    });
});

app.use(express.static(__dirname));
app.get('/*', (req, res) => {
    res.sendFile(path.join(__dirname+'/dist/index.html'));
});

const port = process.env.PORT || 5000;

app.listen(port, () => console.log(`Server started on port ${port}`));

webpack.config.dev.js

const path = require('path');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');

//Module.exports is nodejs syntax
module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: ''
  },
  devtool: 'cheap-module-eval-source-map',
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        loader: "babel-loader",
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: [
          'style-loader','css-loader', 
          {
            loader: 'postcss-loader', // automatically process css code to work in all browsers
            options: {
              ident: 'postcss',
              plugins: () => [autoprefixer()]  // picks up the browserslist value from package.json. This value tells prefixer 
                                               // on how to prefix css properties and which browser needs to be supported.
            }
          }
        ]
      },
      {
        test: /\.(png|jpe?g|gif)$/,
        loader: 'url-loader?limit=8000&name=images/[name].[ext]'
      },
      {
        test: /\.json$/,
        loader: 'json-loader'
      }
    ]
  },
  resolve: {
    extensions: [".js", ".jsx", ".json", ".wasm", ".mjs", "*"]
  },
  plugins: [
    new HtmlWebpackPlugin({                  // pickup bundle.js and use in another bigger file transformation
      template: __dirname + '/public/index.html',  // use index.html as starting point
      filename: 'index.html',
      inject: 'body'
    }),
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"development"'
      },
    })
  ]
};

package.json(客户端文件夹)

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --config webpack.config.dev.js",
    "build:prod": "webpack --config webpack.config.prod.js",
    "lint": "eslint src/"
  },
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "axios": "^0.19.2",
    "immer": "^6.0.2",
    "prop-types": "^15.7.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-redux": "^7.2.0",
    "react-router-dom": "^5.1.2",
    "react-scripts": "3.4.1",
    "react-toastify": "^5.5.0",
    "redux": "^4.0.5",
    "redux-thunk": "^2.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/preset-env": "^7.9.0",
    "@babel/preset-react": "^7.9.4",
    "@babel/preset-stage-2": "^7.8.3",
    "autoprefixer": "^9.7.4",
    "babel-eslint": "^10.1.0",
    "babel-loader": "^8.1.0",
    "css-loader": "^3.4.2",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "eslint": "^6.8.0",
    "eslint-loader": "^3.0.3",
    "eslint-plugin-import": "^2.20.1",
    "eslint-plugin-react": "^7.19.0",
    "file-loader": "^6.0.0",
    "html-webpack-plugin": "^4.0.1",
    "jest": "^25.2.3",
    "json-loader": "^0.5.7",
    "postcss-loader": "^3.0.0",
    "style-loader": "^1.1.3",
    "url-loader": "^4.0.0",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": "> 1%, last 2 versions",
  "proxy": "http://localhost:5000/"
}

package.json(根文件夹)

{
  "name": "beargenes-admin",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "server": "nodemon server.js",
    "client": "npm start --prefix client",
    "dev": "npm-run-all --parallel client server",
    "build:prod": "npm run build:prod --prefix client"
  },
  "author": "SAP",
  "license": "MIT",
  "dependencies": {
    "body-parser": "^1.19.0",
    "bootstrap": "^4.4.1",
    "express": "^4.17.1",
    "react": "^16.13.1",
    "react-bootstrap": "^1.0.0",
    "react-dom": "^16.13.1",
    "reactstrap": "^8.4.1",
    "uuid": "^7.0.2",
    "webpack-dev-server": "^3.10.3"
  },
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/preset-env": "^7.9.0",
    "@babel/preset-react": "^7.9.4",
    "@babel/preset-stage-2": "^7.8.3",
    "babel-loader": "^8.1.0",
    "nodemon": "^2.0.2",
    "npm-run-all": "^4.1.5",
    "webpack": "^4.42.1",
    "webpack-cli": "^3.3.11"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

0 个答案:

没有答案