使用React-Router browserHistory,Wepback 2 historyApiFallback和Node

我尝试使用React,Node,Wepback 2在本地运行我的React应用程序。每当我遇到不是/我得到404的路由时,我的目标是能够运行我的节点服务器,让webpack-dev-服务器运行,使用browserHistory并返回我的webpack的historyApiFallback工作。

目前的工作:

  1. 如果我只运行webpack-dev-server而没有节点服务器,那么browserHistory工作正常,没有404s。
  2. 如果我用hashHistory运行节点,它工作正常,没有404s。

所以这就排除了我的路线不工作。 这里是一些代码:

server.js

 const express = require('express'); const expressGraphQL = require('express-graphql'); const schema = require('./schema'); const app = express(); app.use('/graphql', expressGraphQL({ schema, graphiql: true })); const webpackMiddleware = require('webpack-dev-middleware'); const webpack = require('webpack'); const webpackConfig = require('../webpack.config.js'); app.use(webpackMiddleware(webpack(webpackConfig))); app.listen(process.env.PORT || 5000, () => console.log('Listening')); 

webpack.config.js

 const webpack = require('webpack'); const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const VENDOR_LIBS = [ 'axios', 'react', 'react-dom', 'react-router', 'react-apollo', 'prop-types' ]; module.exports = { entry: { bundle: './client/src/index.js', vendor: VENDOR_LIBS }, output: { path: path.join(__dirname, 'dist'), publicPath: '/', filename: '[name].[chunkhash].js' }, module: { rules: [ { use: 'babel-loader', test: /\.js$/, exclude: /node_modules/ }, { test: /\.scss$/, use: [{ loader: "style-loader" }, { loader: "css-loader" }, { loader: "sass-loader" }] }, { test: /\.(jpe?g|png|gif|svg|)$/, use: [ { loader: 'url-loader', options: {limit: 40000} }, 'image-webpack-loader' ] } ] }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ names: ['vendor', 'manifest'] }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) }), new HtmlWebpackPlugin({ template: './client/src/index.html' }) ], devServer: { historyApiFallback: true } }; 

routes.js

 import React from 'react'; import { Router, Route, IndexRoute, browserHistory } from 'react-router'; import App from './components/App'; import Portal from './components/portal/Portal'; const componentRoutes = { component: App, path: '/', indexRoute: { component: Portal }, childRoutes: [ { path: 'home', getComponent(location, cb) { System.import('./components/homepage/Home') .then(module => cb(null, module.default)); } } ] }; const Routes = () => { return <Router history={ browserHistory } routes={ componentRoutes } /> }; export default Routes; 

再次,目标是能够本地启动我的节点服务器,使用browserHistory而不是404s。 我不想使用hashHistory,我需要使用我的节点服务器,所以我可以使用graphql。 我也不想回到webpack v1。 虽然这里是一个人们在v1下工作的链接:

historyApiFallback在Webpack开发服务器中不起作用

webpack-dev-server选项专门用于webpack-dev-server 。 如果您正在运行自己的服务器,即使使用webpack-dev-middleware ,也需要将其configuration为在出现404时发送index.html 。 因为您正在使用html-webpack-plugin所以您要发送的index.html不存在于您的文件系统中,而只存在于内存中。 要使其工作,您可以访问webpack编译器的输出,如html-webpack-plugin #145的注释中所示。

server.js

 const path = require('path'); const express = require('express'); const expressGraphQL = require('express-graphql'); const schema = require('./schema'); const app = express(); app.use('/graphql', expressGraphQL({ schema, graphiql: true })); const webpackMiddleware = require('webpack-dev-middleware'); const webpack = require('webpack'); const webpackConfig = require('../webpack.config.js'); const compiler = webpack(webpackConfig); app.use(webpackMiddleware(compiler)); // Fallback when no previous route was matched app.use('*', (req, res, next) => { const filename = path.resolve(compiler.outputPath, 'index.html'); compiler.outputFileSystem.readFile(filename, (err, result) => { if (err) { return next(err); } res.set('content-type','text/html'); res.send(result); res.end(); }); }); app.listen(process.env.PORT || 5000, () => console.log('Listening'));