无法使用 react-router v4 获取“/About”(生产帮助)

Posted

技术标签:

【中文标题】无法使用 react-router v4 获取“/About”(生产帮助)【英文标题】:Cannot GET "/About" with react-router v4 (Production Help) 【发布时间】:2018-02-15 16:37:57 【问题描述】:

我一直在阅读 react-router-dom (v4) 的所有文档,以及大量出现相同错误的 Stack Overflow 问题,但是 A) 他们留下了很多未解决的漏洞 B) 他们似乎都建议仅进行开发修复,因此我希望看到人们在 PRODUCTION 中针对这个简单场景实际做了什么,并且 C)我可能在做一些愚蠢的事情,答案对我不起作用,出现错误“不能GET /about" 渲染在控制台中没有错误。

我正在使用 Express、React、Node 并使用 Webpack 进行编译。我可以成功访问我的主页,单击任何链接会将我带到相应的组件,但手动输入 URL 会破坏这一点,正如 here 所讨论的那样,并且此错误的原因已被讨论 here。

大多数答案建议在 webpack.config.js 文件中添加 devServer.historyApiFallback = trueoutput.publicPath = '/',这意味着我还需要运行 npm install --save-dev webpack-dev-server 并按照文档中的建议使用 node_modules/.bin/webpack-dev-server 运行它。做这一切,什么都没有发生。事实上,现在更糟了,因为我也无法访问我的“/”路径。

所以在将我当前的配置放在这里之前,1) 我能做些什么来解决这个问题? 2)它甚至重要吗? webpack-dev-server 显然只用于开发,那么生产呢?

我的 webpack.config.js 文件:

var webpack = require('webpack');
var path = require('path');
var envFile = require('node-env-file');

process.env.NODE_ENV = process.env.NODE_ENV || 'development';

try 
    envFile(path.join(__dirname, 'config/' + process.env.NODE_ENV + '.env'))
 catch (e) 


module.exports = 
    devServer: 
    historyApiFallback: true,
  ,
    entry: [
        'script-loader!foundation-sites/dist/js/foundation.min.js',
        './app/app.jsx'
    ],
    plugins: [
        new webpack.DefinePlugin(
            'process.env': 
                //you don't get to see this
            
        )
    ],
    output: 
        path: __dirname,
        filename: './public/bundle.js',
        publicPath: '/'
    ,
    resolve: 
        modules: [
            __dirname,
            'node_modules',
            './app/components',
            './app/api'
        ],
        alias: 
            app: 'app',
            applicationStyles: 'app/styles/app.scss',
            actions: 'app/actions/actions.jsx',
            configureStore: 'app/store/configureStore.jsx',
            reducers: 'app/reducers/reducers.jsx'
            ),
        ,
        extensions: ['.js', '.jsx']
    ,
    module: 
        rules: [
            
                loader: 'babel-loader',
                query: 
                    presets: ['react', 'es2015', 'stage-0']
                ,
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/
            ,
            
                loader: 'url-loader?limit=100000',
                test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/
            ,
            
                loader: 'sass-loader',
                test: /\.scss$/,
                options: 
                    includePaths: [
                        path.resolve(__dirname, './node_modules/foundation-sites/scss')
                    ]
                
            
        ]
    ,
    devtool: process.env.NODE_ENV === 'production' ? false : 'source-map'
;

我的 app.jsx:

var React = require('react');
var ReactDOM = require('react-dom');
import Provider from 'react-redux';
import BrowserRouter as Router, Route, Switch, Link, HashRouter from 'react-router-dom';

import Home from 'Home';
import Watch from 'Watch';
import About from 'About';
import AddShow from 'AddShow';

var store = require('configureStore').configure();
import firebase from 'app/firebase/';

// Load Foundation
$(document).foundation();

// App css
require('style-loader!css-loader!sass-loader!applicationStyles');

ReactDOM.render(
  <Provider store=store>
    <Router>
      <div>
        <Route exact path="/" component=Home/>
        <Route path="/watch" component=Watch/>
        <Route path="/about" component=About/>
        <Route path="/addshow" component=AddShow/>
      </div>
    </Router>
  </Provider>,
  document.getElementById('app')
);

【问题讨论】:

【参考方案1】:

您必须设置您的网络服务器(通过 react 应用为 index.html 提供服务的服务器)将所有请求重定向到您的 index.html 的 url,以便 react-router 可以完成其工作。这就是对 webpack.config.js 的建议更改对 webpack-dev-server 所做的

在您的 webpack.config.js 中,您需要启用 html 插件,以便 webpack 知道您的 index.html 在哪里:

plugins: [
    new webpack.DefinePlugin(
        'process.env': 
            //you don't get to see this
        
    ),
    new HtmlWebpackPlugin(
        template: 'public/index.html' //or wherever your index.html is
    )
],

【讨论】:

是的,我理解这个概念,但为什么它不起作用。开发服务器在启动时声明:Project is running at http://localhost:8081/ webpack output is served from / 404s will fallback to /index.html 但是当我转到localhost:8081/ 时,我得到Cannot GET / 对于该错误,您需要将 HtmlWebpackPlugin 添加到您的webpack.config.js,我将其添加到答案中 感谢添加确实帮助我通过 webpack-dev-server 让它工作,但如果我只是启动我的 express 服务器它就不起作用,我最终会遇到同样的问题。 “webpack-dev-server” github页面明确声明它仅用于开发,那么人们为生产做什么? 你如何为 react 应用提供服务?您是否将 react 应用程序的生产版本作为 express 的静态资源提供服务?在这种情况下,应该可以将所有请求重定向到您的 index.html 并让 react-router 处理它们,即让您的 GET /about 路由在后端指向 index.html

以上是关于无法使用 react-router v4 获取“/About”(生产帮助)的主要内容,如果未能解决你的问题,请参考以下文章

react-router v4 使用 history 控制路由跳转

如何使用 react-router v4 检测路由变化?

刷新浏览器时如何使react-router v4:id-path工作?

React-router v4教程

使用 Jest 测试来自 react-router v4 的链接

在 react-router v4 中使用 React IndexRoute