React Router v4 nested routes not work with webpack-dev-server

后端 未结 5 1223
感情败类
感情败类 2021-01-13 06:50

I try to setup nested routes for my react app like this

  • / -> Home Page
  • /about -> About Page
  • /protected
相关标签:
5条回答
  • 2021-01-13 07:03

    basically wrap, your react app using <HashRouter> instead of <BrowserRouter> working fine without any webpack config modification, if you don't want to use HashRouter then you can free to use historyApiFallback: true in web pack dev server config on bottom of webpack.config file

    like so
     const config = {
    
    ........
        devServer: {
            compress: true,
            port: 3000,
            https: false,
            historyApiFallback:true
        }
    }
    
    0 讨论(0)
  • 2021-01-13 07:04

    I finally figured out the reason that webpack-dev-server couldn't serve nested routes.

    As a single page application, when you visit /somepath of your react app, it actually fallback to the / and pass the pathname to react router. React router will navigate you to /somepath by the using browser's history API.

    webpack-dev-server, for some unknown reason, doesn't enable this "fallback to history API" behaviour by default.

    So, we need to add historyApiFallback: true, to the devServer of webpack config.

    Now, all top level routes, like /somepath should work, but for nested routes, like /somepath/morepath, it's not enough.

    With default webpack-dev-server setting, the compiled html template will point to the bundled js like <script type="text/javascript" src="main.js"></script>. Pay attention to the src="main.js" which assumes the main.js is under the same path as the index.html. The assumption is true for top level path /somepath but for nested routes, /somepath/morepath, this assumption will lead html file to access main.js like /somepath/main.js.

    So, we end up with looking for a way to specify a certain place for html file when it's going to access the bundled js. And, it's the job of publicPath. Adding publicPath: '/', to the output block of webpack config. It will tell html to always access main.js from / folder and the compiled html will be <script type="text/javascript" src="/main.js"></script>. That's exactly what we're looking for.

    0 讨论(0)
  • 2021-01-13 07:11

    Try adding:

    <base href="/" />

    to the <head> tag of your index.html. This way it'll always look for /main.js bundle, even for nested routes.

    0 讨论(0)
  • 2021-01-13 07:13

    To summarized the answer by @Bing Lu, in your webpack.config.js file:

    module.exports = () => ({
      mode: 'development',
      entry: ...,
      ...,
      output: {
        ...
        publicPath: '/' // <- this is the important line along with historyApiFallback = true in the dev server config
      },
      ...,
      devServer: {
        contentBase: path.join(__dirname, 'dist'),
        historyApiFallback: true,
        compress: true,
        ...
      },
    })
    
    0 讨论(0)
  • 2021-01-13 07:14

    I was having the same problem described in the question (webpack-dev-server not serving nested routes, top level ones working fine). Sadly, neither historyApiFallback: true nor publicPath: '/' were working. Actually, the problem was inside index.html, more precisely inside <script src="bundle.js"></script>. Changing to

    <script src="/bundle.js"></script>       <!-- do include slash before the file name -->
    

    was enough to end the pain.

    0 讨论(0)
提交回复
热议问题