Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/423.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何允许Web包开发服务器允许来自react路由器的入口点_Javascript_Reactjs_Webpack_React Router - Fatal编程技术网

Javascript 如何允许Web包开发服务器允许来自react路由器的入口点

Javascript 如何允许Web包开发服务器允许来自react路由器的入口点,javascript,reactjs,webpack,react-router,Javascript,Reactjs,Webpack,React Router,我正在创建一个应用程序,它使用正在开发中的WebpackDevServer和react路由器 webpack dev server似乎是基于这样的假设构建的:您将在一个地方(即“/”)拥有一个公共入口点,而react router允许无限量的入口点 我想要webpack dev服务器的好处,特别是热重新加载功能,这对提高生产率非常重要,但我仍然希望能够加载react router中设置的路由 如何实现这一点,使它们能够协同工作?您是否可以在webpack dev server前面运行expres

我正在创建一个应用程序,它使用正在开发中的WebpackDevServer和react路由器

webpack dev server似乎是基于这样的假设构建的:您将在一个地方(即“/”)拥有一个公共入口点,而react router允许无限量的入口点

我想要webpack dev服务器的好处,特别是热重新加载功能,这对提高生产率非常重要,但我仍然希望能够加载react router中设置的路由


如何实现这一点,使它们能够协同工作?您是否可以在webpack dev server前面运行express server,以实现此目的?

我设置了一个代理来实现此目的:

您有一个常规的express Web服务器,它在任何路由上提供index.html,除非它是一个资产路由。如果它是一个资产,那么请求将被代理到web开发服务器

您的react热入口点仍将直接指向webpack dev服务器,因此热重新加载仍然有效

假设您在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进行热重新加载

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

 output: {
     publicPath: "http://localhost:8081/assets/",
     // ...
 }

您应该将
WebpackDevServer
historyApiFallback
设置为true,这样才能工作。下面是一个小示例(根据您的目的进行调整):


我想补充一下,当您运行同构应用程序时(即,在服务器端渲染React组件),这种情况的答案

在这种情况下,您可能还希望在更改某个组件时自动重新加载服务器。您可以使用
管道
包执行此操作。您所要做的就是安装它并在server.js的开头添加
require(“piping”)({hook:true})
。就这样。更改服务器使用的任何组件后,服务器将重新启动

不过,这会引发另一个问题-如果您从与express server相同的进程运行webpack server(如上面接受的答案所示),webpack server也会重新启动,并且每次都会重新编译您的包。为了避免这种情况,您应该在不同的进程中运行主服务器和网页包服务器,这样管道将只重新启动express服务器,而不会触动网页包。 您可以同时使用
包执行此操作。您可以在中找到这方面的示例。在package.json中,他有:


它同时运行两台服务器,但在不同的进程中。

对于可能仍在寻找此答案的任何其他人。我创建了一个简单的代理旁路,它可以轻松地实现这一点,并且将配置文件放入webpack.config.js中

我确信有很多更优雅的方法可以使用regex测试本地内容,但这适合我的需要

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';
        }
      }
    }
  }
} 

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

module.exports={
条目:“index.js”,
输出:{
文件名:“bundle.js”
},
开发服务器:{
历史上的倒退:正确
}

}
历史APIfallback
也可以是包含路由的对象,而不是布尔值

historyApiFallback: navData && {
  rewrites: [
      { from: /route-1-regex/, to: 'route-1-example.html' }
  ]
}

可能并非所有情况下都是如此,但devServer中的
publicPath:'/'
选项似乎是解决深度路由问题的最简单的解决方案,请参阅:

这对我来说很有效:只需先添加webpack中间件,然后再添加
app.get('*')…
index.html解析器

因此,express将首先检查请求是否匹配webpack提供的路由之一(如:
/dist/bundle.js
/\uuuuuWebpack\uhmr
),如果不匹配,则将使用
*
解析器移动到
index.html

即:


对于最近的答案,当前版本的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:

"scripts": {
    "start": "webpack-dev-server --config ./webpack.config.js --mode development"
  },

我这里有一个非常黑的版本,但它很脆弱,只允许简单的路由匹配:(参见makewebpack-config)和(app/routes.js)你解决这个问题了吗Nathan?如果是,怎么解决?请尝试在这里回答我的问题。谢谢..!嘿,这太棒了。事实上,我在这之前不久就到达了这个设置,并打算发布一个答案,但我认为你做得更好。一个问题,有点不相关,因此如果需要,我可以打开一个新问题,但我注意到现在webpack dev服务器的NSLE输出不是流式的。以前,你可以看到它编译并看到百分比上升,现在它只是在编译后阻止输出。做得很好。这正是应该做的。我添加了一个关于
输出.publicPath
选项的注释,该选项也应该是一个绝对url。使用bu更简单改为ilt。这样,您就不会干扰服务器本身,而是让服务器保持纯净。相反,您只需在webpack配置中添加一点(3-5行)。因此,您只需出于开发目的修改开发脚本,并让生产代码(server.js)保持平静(与您的版本不同)在我看来,这是正确的方法。这个答案虽然有点过时,但仍然是正确的。现在有了更简单的方法,请查找
historyApiFallback
。您将错过index.html顶部的状态栏,但效果很好:)这应该是公认的答案。来自webpack dev server docs:“如果您使用的是HTML5历史API,您可能需要提供index.html来代替404响应,这可以通过设置historyApiFallback:true来实现。”如果我正确理解问题,这将解决问题。如此简单。。。谢谢大家!@smnbbrv没有问题。它实际上使用底层,如果需要,您可以使用中间件特定的选项传递对象
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)
})
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
    }
  };
"scripts": {
    "start": "webpack-dev-server --config ./webpack.config.js --mode development"
  },