historyApiFallback 也可以是包含路径的对象而不是布尔值。
historyApiFallback
historyApiFallback: navData && { rewrites: [ { from: /route-1-regex/, to: 'route-1-example.html' } ] }
如果您使用CLI运行webpack-dev-server,则可以通过webpack.config.js传递devServer对象来配置它:
module.exports = { entry: "index.js", output: { filename: "bundle.js" }, devServer: { historyApiFallback: true } }
每当遇到404时,这将重定向到index.html。
注意:如果您使用的是publicPath,则还需要将其传递给devServer:
module.exports = { entry: "index.js", output: { filename: "bundle.js", publicPath: "admin/dashboard" }, devServer: { historyApiFallback: { index: "admin/dashboard" } } }
您可以通过查看输出的前几行来验证是否已正确设置所有内容(具有“404s的部分将回退到: 的 路径 强> “)。
我想在运行同构应用程序(即呈现React组件服务器端)时添加案例的答案。
在这种情况下,您可能还希望在更改其中一个React组件时自动重新加载服务器。你这样做 piping 包。您所要做的就是安装并添加 require("piping")({hook: true}) 在你的开始的某个地方 server.js 。而已。更改任何组件后,服务器将重新启动。
piping
require("piping")({hook: true})
这引发了另一个问题 - 如果你从与快速服务器相同的进程运行webpack服务器(如上面接受的答案),webpack服务器也将重新启动,并且每次都会重新编译你的软件包。为避免这种情况,您应该在不同的进程中运行主服务器和webpack服务器,以便管道只重新启动您的快速服务器,并且不会触及webpack。 你可以这样做 concurrently 包。你可以在其中找到一个例子 反应不同构-STARTERKIT 。在里面 的package.json 他有:
concurrently
"scripts": { ... "watch": "node ./node_modules/concurrently/src/main.js --kill-others 'npm run watch-client' 'npm run start'" },
它同时运行两个服务器但在不同的进程中运行
可能并非在所有情况下,但似乎是 publicPath: '/' devServer中的选项是解决深层路由问题最简单的解决方案,请参阅: https://github.com/ReactTraining/react-router/issues/676
publicPath: '/'
这对我有用:只需先添加webpack中间件即可 app.get('*'... index.html解析器后来,
app.get('*'...
所以express将首先检查请求是否与webpack提供的路由匹配(例如: /dist/bundle.js 要么 /__webpack_hmr_ 如果没有,那么它将移动到 index.html 随着 * 解析器。
/dist/bundle.js
/__webpack_hmr_
index.html
*
即:
app.use(require('webpack-dev-middleware')(compiler, { publicPath: webpackConfig.output.publicPath, })) app.use(require('webpack-hot-middleware')(compiler)) app.get('*', function(req, res) { sendSomeHtml(res) })
对于更新的答案,当前版本的webpack(4.1.1)你可以在你的webpack.config.js中设置这样的:
const webpack = require('webpack'); module.exports = { entry: [ 'react-hot-loader/patch', './src/index.js' ], module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: ['babel-loader'] }, { test: /\.css$/, exclude: /node_modules/, use: ['style-loader','css-loader'] } ] }, resolve: { extensions: ['*', '.js', '.jsx'] }, output: { path: __dirname + '/dist', publicPath: '/', filename: 'bundle.js' }, plugins: [ new webpack.HotModuleReplacementPlugin() ], devServer: { contentBase: './dist', hot: true, historyApiFallback: true } };
重要的是 historyApiFallback: true 。 cli:无需运行自定义服务器,只需使用cli:
historyApiFallback: true
"scripts": { "start": "webpack-dev-server --config ./webpack.config.js --mode development" },
我设置了一个代理来实现这个目标:
您有一个常规的快速网络服务器,可以在任何路由上为index.html提供服务,除非是资产路由。如果它是资产,请求将被代理到web-dev-server
您的反应热入口点仍将直接指向webpack开发服务器,因此热重新加载仍然有效。
假设您在8081上运行webpack-dev-server,在8080运行代理。您的server.js文件将如下所示:
"use strict"; var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var config = require('./make-webpack-config')('dev'); var express = require('express'); var proxy = require('proxy-middleware'); var url = require('url'); ## --------your proxy---------------------- var app = express(); ## proxy the request for static assets app.use('/assets', proxy(url.parse('http://localhost:8081/assets'))); app.get('/*', function(req, res) { res.sendFile(__dirname + '/index.html'); }); # -----your-webpack-dev-server------------------ var server = new WebpackDevServer(webpack(config), { contentBase: __dirname, hot: true, quiet: false, noInfo: false, publicPath: "/assets/", stats: { colors: true } }); ## run the two servers server.listen(8081, "localhost", function() {}); app.listen(8080);
现在在webpack配置中创建入口点,如下所示:
entry: [ './src/main.js', 'webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8081' ]
注意直接调用8081进行热重载
还要确保你传递一个绝对的网址 output.publicPath 选项:
output.publicPath
output: { publicPath: "http://localhost:8081/assets/", // ... }
对于其他可能仍在寻找此答案的人。我把一个简单的代理旁路放在一起,没有太多麻烦,配置进入webpack.config.js
我确信有更优雅的方法可以使用正则表达式测试本地内容,但这符合我的需求。
devServer: { proxy: { '/**': { //catch all requests target: '/index.html', //default target secure: false, bypass: function(req, res, opt){ //your custom code to check for any exceptions //console.log('bypass check', {req: req, res:res, opt: opt}); if(req.path.indexOf('/img/') !== -1 || req.path.indexOf('/public/') !== -1){ return '/' } if (req.headers.accept.indexOf('html') !== -1) { return '/index.html'; } } } } }
你应该设置 historyApiFallback 的 WebpackDevServer 这是正确的工作。这是一个小例子(调整以适合您的目的):
WebpackDevServer
var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var config = require('./webpack.config'); var port = 4000; var ip = '0.0.0.0'; new WebpackDevServer(webpack(config), { publicPath: config.output.publicPath, historyApiFallback: true, }).listen(port, ip, function (err) { if(err) { return console.log(err); } console.log('Listening at ' + ip + ':' + port); });