我使用Webpack开发服务器和反应路由器中的browserHistory通过HTML5历史API操纵urls。历史回顾-选项在我的webpack配置文件中不工作。在刷新http://localhost:8080/users或http://localhost:8080/products之后,我得到了404。
webpack.config.js
var webpack = require('webpack');
var merge = require('webpack-merge');
const TARGET = process.env.npm_lifecycle_event;
var common = {
    cache: true,
    debug: true,
    entry: './src/script/index.jsx',
    resolve: {
        extensions: ['', '.js', '.jsx']
    },
    output: {
        sourceMapFilename: '[file].map'
    },
    module: {
        loaders: [
            {
                test: /\.js[x]?$/,
                loader: 'babel-loader',
                exclude: /(node_modules)/
            }
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
        })
    ]
};
if(TARGET === 'dev' || !TARGET) {
    module.exports = merge(common,{
        devtool: 'eval-source-map',
        devServer: {
            historyApiFallback: true
        },
        output: {
            filename: 'index.js',
            publicPath: 'http://localhost:8090/assets/'
        },
        plugins: [
            new webpack.DefinePlugin({
                'process.env.NODE_ENV': JSON.stringify('dev')
            })
        ]
    });
}index.html
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
        <title>Test</title>
    </head>
    <body>
        <div id="content">
            <!-- this is where the root react component will get rendered -->
        </div>
        <script src="http://localhost:8090/webpack-dev-server.js"></script>
        <script type="text/javascript" src="http://localhost:8090/assets/index.js"></script>
    </body>
</html>index.jsx
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, useRouterHistory, browserHistory, Link} from 'react-router';
class Home extends Component{
  constructor(props) {
    super(props);
  }
  render() {
      return <div>
          I am home component
          <Link to="/users" activeClassName="active">Users</Link>
          <Link to="/products" activeClassName="active">Products</Link>
        </div>;
  }
}
class Users extends Component{
  constructor(props) {
    super(props);
  }
  render() {
      return <div> I am Users component </div>;
  }
}
class Products extends Component{
  constructor(props) {
    super(props);
  }
  render() {
      return <div> I am Products component </div>;
  }
}
ReactDOM.render(
    <Router history={browserHistory} onUpdate={() => window.scrollTo(0, 0)}>
        <Route path="/" component={Home}/>
        <Route path="/users" component={Users} type="users"/>
        <Route path="/products" component={Products} type="products"/>
    </Router>
    , document.getElementById('content'));package.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.jsx",
  "scripts": {
    "start": "npm run serve | npm run dev",
    "serve": "./node_modules/.bin/http-server -p 8080",
    "dev": "webpack-dev-server -d --progress --colors --port 8090 --history-api-fallback"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "events": "^1.1.0",
    "jquery": "^2.2.3",
    "path": "^0.12.7",
    "react": "^15.0.2",
    "react-dom": "^15.0.2",
    "react-mixin": "^3.0.5",
    "react-router": "^2.4.0"
  },
  "devDependencies": {
    "babel": "^6.5.2",
    "babel-core": "^6.8.0",
    "babel-loader": "^6.2.4",
    "babel-polyfill": "^6.8.0",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babel-register": "^6.8.0",
    "http-server": "^0.9.0",
    "webpack": "^1.13.0",
    "webpack-dev-server": "^1.14.1",
    "webpack-merge": "^0.12.0"
  }
}我试图在我的配置中更改devServer,但是它没有帮助:
devServer: {
    historyApiFallback: {
        index: 'index.html',
    }
},
devServer: {
    historyApiFallback: {
        index: 'index.js',
    }
},
devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets',
    }
},
devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets/',
    }
},
devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets/index.html',
    }
},
devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets/index.js',
    }
},
devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets/index.js',
    }
},
output: {
    filename: 'index.js',
            publicPath: 'http://localhost:8090/assets/'
},发布于 2021-05-07 01:59:53
这里发生了一件非常棘手的事情!
下面的404可以是,两个完全不同的。您可以打开Chrome的“网络”选项卡,看看是最初的请求是404,还是内部的资产。
如果您不害怕终端,也可以做curl -v http://localhost:8081/product来查看实际的HTTP响应代码。
案例1:初始HTML页面上的404
在这种情况下,设置historyFallbackApi是不正确的。
通常,只有historyApiFallback: true应该在Webpack的devServer吐露中工作。(来源)但是,如果您碰巧有一个自定义的output文件夹,则必须将historyApiFallback的index属性设置为相同的路径,就像对jsdeveloper's或切津氏这样的问题的其他答案所建议的那样。
案例2: 404关于资产(例如bundle.js或vendor.js)
这个很有趣!
在本例中,您确实获得了初始的view-source: (即,如果在view-source:http://localhost:8081/admin之前添加view-source:http://localhost:8081/admin,则会看到HTML和/或curl命令显示HTML),但页面在浏览器中无法工作。
historyApiFallback所做的事情,听起来可能很神奇,实际上只是将快速服务器的req.url设置为index.html文件,用于域中的任何传入GET请求。(源代码中的主要两行)
但是,如果您的资产的路径是相对的(例如,在视图源中,您看到了<script src="vendor.js"></script>) 和,那么您要登陆的路径与索引的路径深度不同(例如,当主服务器位于http://localhost:8081/admin时,您正在尝试加载http://localhost:8081/admin/user/12/summary ),那么它将无法为您的JavaScript代码找到.js文件。(就我而言,http://localhost:8081/admin/user/12/vendor.js)

请注意,这里处理HTML5历史记录的任何路由器(react路由器或vue路由器)都知道如何在初始负载时初始化到document.location.href的内部路径。但是,它不知道正确更新资产路径的“根”在哪里。(就责任而言,这甚至都不是它的工作。)因此,资产路径将根据URL的路径计算,而不是index.html的路径!因此,对于没有绝对/前缀的src="vendor.js",它尝试查找/admin/user/12/vendor.js而不是/vendor.js。
这里您需要做的是确保您的output路径是WebPack的,一个绝对路径,并以/开头,所以不管登陆URL如何,它总是可以工作的。也就是说,它始终是<script src="/vendor.js"></script>源文件中的HTML。
要做到这一点,您必须将output.publicPath设置为绝对路径(有域还是不带域)。您可以通过上面的view-source:或curl技术验证这一点。:)
https://stackoverflow.com/questions/37271062
复制相似问题