如何允许webpack-dev-server允许来自react-router的入口点

Nat*_*ert 109 javascript reactjs webpack react-router

我正在创建一个使用webpack-dev-server开发的应用程序以及react-router.

似乎webpack-dev-server是基于这样的假设,即在一个地方(即"/")有一个公共入口点,而react-router允许无限量的入口点.

我想要webpack-dev-server的好处,特别是热量重新加载功能,这对于提高工作效率很有帮助,但我仍然希望能够加载在react-router中设置的路由.

如何实现它以便它们一起工作?你能以这种方式在webpack-dev-server前运行快速服务器吗?

Juh*_*nen 100

你应该设置historyApiFallbackWebpackDevServer是真正为这个工作.这是一个小例子(调整以适合您的目的):

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);
});
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案.从webpack dev服务器docs:_"如果您正在使用HTML5历史API,您可能需要提供index.html来代替404响应,这可以通过设置historyApiFallback来实现:true"_如果我正确理解了这个问题将解决问题. (7认同)

Ret*_*ozi 68

我设置了一个代理来实现这个目标:

您有一个常规的快速网络服务器,可以在任何路由上为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);
Run Code Online (Sandbox Code Playgroud)

现在在webpack配置中创建入口点,如下所示:

 entry: [
     './src/main.js',
     'webpack/hot/dev-server',
     'webpack-dev-server/client?http://localhost:8081'
 ]
Run Code Online (Sandbox Code Playgroud)

注意直接调用8081进行热重载

还要确保将绝对URL传递给output.publicPath选项:

 output: {
     publicPath: "http://localhost:8081/assets/",
     // ...
 }
Run Code Online (Sandbox Code Playgroud)

  • 使用内置的[webpack代理](https://webpack.github.io/docs/webpack-dev-server.html#proxy)会更容易.因此,您不会干扰服务器本身,而是离开服务器_pure_.相反,你只需要在webpack配置中添加一些(3-5行).多亏了你只为开发目的修改dev脚本并保持生产代码(server.js)安静(与你的版本不同)和imo这是正确的方法. (5认同)
  • 虽然有点过时但这个答案仍然是正确的.现在有更直接的方法,寻找`historyApiFallback`. (3认同)

小智 25

对于其他可能仍在寻找此答案的人.我把一个简单的代理旁路放在一起,没有太多麻烦,配置进入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';
        }
      }
    }
  }
} 
Run Code Online (Sandbox Code Playgroud)


Eug*_*hov 10

如果您使用CLI运行webpack-dev-server,则可以通过webpack.config.js传递devServer对象来配置它:

module.exports = {
  entry: "index.js",
  output: {
    filename: "bundle.js"
  },
  devServer: {
    historyApiFallback: true
  }
}
Run Code Online (Sandbox Code Playgroud)

每当遇到404时,这将重定向到index.html.

注意:如果您使用的是publicPath,则还需要将其传递给devServer:

module.exports = {
  entry: "index.js",
  output: {
    filename: "bundle.js",
    publicPath: "admin/dashboard"
  },
  devServer: {
    historyApiFallback: {
      index: "admin/dashboard"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以通过查看输出的前几行(具有"404s将回退到:path "的部分)来验证是否已正确设置所有内容.

在此输入图像描述


Mic*_*own 8

对于更新的答案,当前版本的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
    }
  };
Run Code Online (Sandbox Code Playgroud)

重要的是historyApiFallback: true.cli:无需运行自定义服务器,只需使用cli:

"scripts": {
    "start": "webpack-dev-server --config ./webpack.config.js --mode development"
  },
Run Code Online (Sandbox Code Playgroud)