React History The Webpack configuration does not take effect

Abstract: When doing a React learning project, I initially used hash routing mode for development. Later, I wanted to switch to history routing mode. Then change the routing mode to BrowserRouter, of course, if the configuration is not modified, direct access is certainly unsuccessful. In hash routing mode, when front-end resource access is performed, the route changes only the hash and does not send requests to the back-end. In history routing mode, the address in the browser address bar changes and requests are sent to the server. At this time we did not carry out similar proxy configuration, the request is definitely unsuccessful.

Changing a Routing Mode

Replace HashRouter with BrowserRouter

// Comment out the HashRouter route import mode. Replace with BrowserRouter
// import { HashRouter } from "react-router-dom";
import { BrowserRouter } from "react-router-dom";
// Use react-router-config to configure routes
import { renderRoutes } from "react-router-config";
// Custom route configuration
import routes from "./router";

ReactDOM.render(
  <BrowserRouter basename="/">{renderRoutes(routes)}</BrowserRouter>.document.getElementById("app"));Copy the code

Modify the WebPack configuration

Bingzhe quickly understand the configuration and solve the problem of thinking (take doctrine 🐶), baidu directly under the relevant configuration, get the relevant search results for configuration file modification. This section provides only the configuration information involved in the modification. The historyApiFallback configuration item can be configured in devServer as follows:

// webpack.dev.js
module.exports = merge(common, {
  mode: "development".devtool: "cheap-module-eval-source-map".output: {
    path: path.resolve(__dirname, '.. /release'),
    publicPath: path.resolve(__dirname, '.. /release')},devServer: {
    historyApiFallback: true.// Add this line of code. When using the HTML5 History API, any 404 response may need to be replaced with index.html
    stats: "errors-only".compress: true.port: 8081.hot: true.open: true.proxy: {
      "/api": {
        target: "http://proxy.test.cn".changeOrigin: true,},},}});Copy the code

Modifications involved:

module.exports = merge(common, {
  / / new
  output: {
    path: path.resolve(__dirname, '.. /release'),
    publicPath: path.resolve(__dirname, '.. /release')},devServer: {
    / / new
    historyApiFallback: true.// Add this line of code. When using the HTML5 History API, any 404 response may need to be replaced with index.html}});Copy the code

Run the debug

Because I did not go to the official website to check the relevant configuration (official website link). So after modification, run to verify that the configuration is correct. I thought it would work. But when to run after, found that when visit http://localhost:8081/ or other routing http://localhost:8081/login the following results are obtained.

If you fail, you always GET Cannot GET /. The conventional wisdom is to keep searching, whether it’s Baidu or StackOverflow. In fact, it ignores the most important resources of the official website. Each configuration field is described on the official website. We can avoid a lot of problems just by being careful and paying attention to the function of each field configuration.

PublicPath instructions.

If we configure publicPath, devServer will load static resources from publicPath, and this path will be configured with a full URL, making sure devServer.publicPath always starts and ends with a slash (/). We make the following adjustments:

    publicPath: '/release/'
Copy the code

That at this point we access path should be http://localhost:8081/release/. We found the resource found! The HTML template is properly loaded. However, such as http://localhost:8081/login to access or not. Because our static resources are in the release path. So the http://localhost:8081/login access method, must get less than HTML templates, render the routing is not successful.

The solution

We have two solutions:

  1. Go to default Settings

Delete the publicPath configuration. The default value is /. Visit http://localhost:8081/ or http://localhost:8081/login can get the template at this time. Route redirects are controlled by the React -router.

output: {
    path: path.resolve(__dirname, '.. /release'),},historyApiFallback: true.Copy the code
  1. Override access route
output: {
    path: path.resolve(__dirname, '.. /release'),
    publicPath: '/release/'
},
historyApiFallback: {
    rewrites: [{from: /. * /,
        to: '/release/'}},Copy the code

We change historyApiFallback: True to an object and rewrite the request path. The default path for any request is /release/, so that we can match our publicPath and get the HTML template file.