问题
I am testing out react-router4 with webpack4, but I can't get webpack-dev-server's setting:
{historyApiFallback: true}
to work. This use to work just fine in webpack3, so I am not sure what is wrong... Here is my webpack.config.js:
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = () => {
  return {
    mode: 'development',
    devtool: 'source-map',
    devServer: {
      port: 8888,
      historyApiFallback: true,
      stats: 'minimal'
    },
    resolve: {
      extensions: ['*', '.mjs', '.js', '.jsx']
    },
    module: {
      rules: [
        {
          test: /\.m?jsx?$/,
          exclude: /(node_modules)/,
          use: {
            loader: 'babel-loader'
          }
        }
      ]
    },
    plugins: [
      new HtmlWebpackPlugin({
        title:'React Lab',
        template: 'src/index.html'
      })
    ]
  }
}
and here is my simple react app with react-router4:
import React from 'react';
import ReactDOM  from 'react-dom';
import {
  BrowserRouter as Router,
  Route,
  Link,
  Switch
} from 'react-router-dom';
const mountNode = document.getElementById('app');
const App = () => (
  <Router>
    <div>
      <ul>
        <li><Link to="/">Link to: /</Link></li>
        <li><Link to="/page1">Link to: /page1</Link></li>
        <li><Link to="/page2">Link to: /page2</Link></li>
        <li><Link to="/does/not/exist">Link to: /does/not/exist</Link></li>
      </ul>
      <button onClick={()=>{location.reload();}}>reload page</button>
      <Switch>
        <Route exact path="/"      component={()=>(<h2>home</h2>)} />
        <Route exact path="/page1" component={()=>(<h2>page1</h2>)} />
        <Route exact path="/page2" component={()=>(<h2>page2</h2>)} />
        <Route                     component={()=>(<h2>no match</h2>)} />
      </Switch>
      <Route path="/" component={(props) =><div>{`props.location.pathname: ${props.location.pathname}`}</div>} />
    </div>
  </Router>
);
ReactDOM.render( <App/>, mountNode
After navigating to:
<Link to="/does/not/exist" /> 
and click
<button>reload page</button>
webpack dev server fail to redirect to main.js
Here is the complete code at github: https://github.com/ApolloTang/webpack-dev-server-history-api-fall-back-not-working.
Any help or comment would greatly appreciated.
回答1:
It turns out that I am missing output.publicPath in webpack.config.js:
output: {
  //  must specified output.publicPath otherwise
  //  devServer.historyApiFallback will not work
  publicPath: '/'
},
with output.publicPath specified as above, historyApiFallback works.
I can't remember where I have read that said output.publicPath is an optional in webpack4's configuration, but it does required to work with webpack-dev-server.
The documentation at https://webpack.js.org/configuration/output/#output-publicpath said:
The webpack-dev-server also takes a hint from publicPath, using it to determine where to serve the output files from.
But I don't understand how is this to do with hisitoryApiFallback.
回答2:
It seems your output.publicPath must match devServer.historyApiFallback.index.
I wonder why that is not automatically implied, in the same manner DevServer reuses output.publicPath unless otherwise specified.
来源:https://stackoverflow.com/questions/53387756/webpack-dev-server-historyapifallback-not-working-webpack-4-react-router-4